【字符串哈希】The 16th UESTC Programming Contest Preliminary F - Zero One Problem

题意:给你一个零一矩阵,q次询问,每次给你两个长宽相同的子矩阵,问你它们是恰好有一位不同,还是完全相同,还是有多于一位不同。

对每行分别哈希,先一行一行地尝试匹配,如果恰好发现有一行无法对应,再对那一行内部进行暴力找出那一行内部有几位不同即可。

#include<cstdio>
using namespace std;
typedef unsigned long long ull;
int n,m,q;
char a[1005][1005];
ull b[1005][1005],pw[1005];
int sum[1005][1005];
//int Abs(int x){
//	return x<0 ? (-x) : x;
//}
int calc(int x1,int y1,int x2,int y2){
	return sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1];
}
int main(){
	//freopen("d.in","r",stdin);
	pw[0]=1;
	for(int i=1;i<=1001;++i){
		pw[i]=pw[i-1]*(ull)233;
	}
	int l[5],r[5];
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%s",a[i]+1);
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			sum[i][j]=sum[i-1][j]+a[i][j]-'0';
		}
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			sum[i][j]+=sum[i][j-1];
		}
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			b[i][j]=b[i][j-1]*(ull)233+(ull)(a[i][j]-'0');
		}
	}
	scanf("%d",&q);
	for(;q;--q){
		for(int j=1;j<=4;++j){
			scanf("%d%d",&l[j],&r[j]);
			++l[j];
			++r[j];
		}
//		int t1=calc(l[1],r[1],l[2],r[2]);
//		int t2=calc(l[3],r[3],l[4],r[4]);
//		if(Abs(t1-t2)>1){
//			puts("Wrong");
//			continue;
//		}
		int kuan=r[2]-r[1]+1,cnt=0,I,J;
		for(int i=l[1],j=l[3];i<=l[2];++i,++j){
			ull hs11=b[i][r[2]]-(b[i][r[1]-1]*pw[kuan]);
			ull hs21=b[j][r[4]]-(b[j][r[3]-1]*pw[kuan]);
			if(!(hs11==hs21)){
				++cnt;
				I=i;
				J=j;
				if(cnt>1){
					break;
				}
			}
		}
		if(cnt>1){
			puts("Wrong");
			continue;
		}
		else if(cnt==0){
			puts("Perfect");
			continue;
		}
		cnt=0;
		for(int k1=r[1],k2=r[3];k1<=r[2];++k1,++k2){
			if(a[I][k1]!=a[J][k2]){
				++cnt;
				if(cnt>1){
					break;
				}
			}
		}
		if(cnt>1){
			puts("Wrong");
		}
		else{
			puts("One difference");
		}
	}
	return 0;
}
posted @ 2018-03-24 23:26  AutSky_JadeK  阅读(289)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト