zoukankan      html  css  js  c++  java
  • 【字符串哈希】The 16th UESTC Programming Contest Preliminary F

    题意:给你一个零一矩阵,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;
    }
  • 相关阅读:
    Linux C Socket编程原理及简单实例
    clock_gettime 用法
    Linux未来监控tracing框架——eBPF
    eBPF监控工具bcc系列五工具funccount
    【转】如何测量电源纹波?
    【转】在网页中运行VB6程序
    如何为互阻抗放大器电路选择具有足够带宽的运算放大器
    互阻放大器的稳定工作及其评估
    【原创】OPA857 TEST模式使用
    [转]What you need to know about transimpedance amplifiers – part 1
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/8642028.html
Copyright © 2011-2022 走看看