【贪心】Google Code Jam Round 1A 2018 Waffle Choppers

题意:给你一个矩阵,有些点是黑的,让你横切h刀,纵切v刀,问你是否能让切出的所有子矩阵的黑点数量相等。

设黑点总数为sum,sum必须能整除(h+1),进而sum/(h+1)必须能整除(v+1)。

先考虑横行,贪心地扫过去,如果到了某一行,当前统计的黑点数恰好为sum/(h+1),就在这里切一刀,接着统计。否则,如果>sum/(h+1),则无解。在这个过程中,每一行被切到哪一横组里就确定了。

然后纵切,过程跟横切类似,只不过统计的不是一个变量,而是一个大小为(h+1)的数组,如果到了某一列,当前统计的数组的每个分量的黑点数恰好为sum/(h+1)/(v+1),就在这里切一刀,接着统计。否则,如果数组的某个分量>sum/(h+1),则无解。

#include<cstdio>
#include<cstring>
using namespace std;
int T,n,m,h,v;
char a[105][105];
int hq[105];
int cnts[105],t;
bool check1(){
	for(int i=1;i<=h+1;++i){
		if(cnts[i]!=t){
			return 0;
		}
	}
	return 1;
}
bool check2(){
	for(int i=1;i<=h+1;++i){
		if(cnts[i]>t){
			return 0;
		}
	}
	return 1;
}
int main(){
	//freopen("a.in","r",stdin);
	scanf("%d",&T);
	for(int zu=1;zu<=T;++zu){
		printf("Case #%d: ",zu);
		scanf("%d%d%d%d",&n,&m,&h,&v);
		for(int i=1;i<=n;++i){
			scanf("%s",a[i]+1);
		}
		int sum=0;
		for(int i=1;i<=n;++i){
			for(int j=1;j<=m;++j){
				sum+=(a[i][j]=='@');
			}
		}
		if(sum%(h+1)!=0){
			puts("IMPOSSIBLE");
			continue;
		}
		t=sum/(h+1);
		int cnt=0;
		bool flag=1;
		int last=0,num=0;
		for(int i=1;i<=n;++i){
			for(int j=1;j<=m;++j){
				cnt+=(a[i][j]=='@');
			}
			if(cnt==t){
				++num;
				for(int k=last+1;k<=i;++k){
					hq[k]=num;
				}
				last=i;
				cnt=0;
			}
			else if(cnt>t){
				flag=0;
				break;
			}
		}
		if(!flag){
			puts("IMPOSSIBLE");
			continue;
		}
		
		if(sum/(h+1)%(v+1)!=0){
			puts("IMPOSSIBLE");
			continue;
		}
		t=sum/(h+1)/(v+1);
		memset(cnts,0,sizeof(int)*(2+h));
		flag=1;
		for(int i=1;i<=m;++i){
			for(int j=1;j<=n;++j){
				cnts[hq[j]]+=(a[j][i]=='@');
			}
			if(check1()){
				memset(cnts,0,sizeof(int)*(2+h));
			}
			else if(!check2()){
				flag=0;
				break;
			}
		}
		if(!flag){
			puts("IMPOSSIBLE");
			continue;
		}
		puts("POSSIBLE");
	}
	return 0;
}
posted @ 2018-04-14 23:55  AutSky_JadeK  阅读(338)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト