POJ3690+位运算

题意:给定一个01矩阵。T个询问,每次询问大矩阵中是否存在这个特定的小矩阵。

  1 /*
  2 64位的位运算!!!
  3 题意:
  4 给定一个01矩阵。T个询问,每次询问大矩阵中是否存在这个特定的小矩阵。
  5 (64位记录状态!!!)
  6 */
  7 #include<stdio.h>
  8 #include<string.h>
  9 #include<stdlib.h>
 10 #include<algorithm>
 11 #include<iostream>
 12 #include<queue>
 13 #include<map>
 14 #include<stack>
 15 #include<set>
 16 #include<math.h>
 17 using namespace std;
 18 typedef long long int64;
 19 //typedef __int64 int64;
 20 typedef pair<int64,int64> PII;
 21 #define MP(a,b) make_pair((a),(b)) 
 22 const int maxn = 1005;
 23 const int maxm = 55;
 24 const int inf = 0x7fffffff;
 25 const double pi=acos(-1.0);
 26 const double eps = 1e-8;
 27 
 28 char mat[ maxn ][ maxn ];
 29 char tmp[ maxm ][ maxm ];
 30 int64 A[ maxn ][ maxn ];
 31 int64 AA[ maxm ];
 32 int64 sum[ maxn ][ maxn ];
 33 
 34 void init( int n,int m,int p,int q ){
 35     for( int i=0;i<=m;i++ )
 36         sum[0][i] = 0;
 37     for( int i=0;i<=n;i++ )
 38         sum[i][0] = 0;
 39     for( int i=1;i<=n;i++ ){
 40         for( int j=1;j<=m;j++ ){
 41             sum[ i ][ j ] = sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1];
 42             if( mat[i][j]=='*' ) 
 43                 sum[i][j] ++;
 44         }
 45     }    
 46     memset( A,0,sizeof( A ) );
 47     for( int i=1;i<=n;i++ ){
 48         for( int j=1;j<=q;j++ ){
 49             if( mat[i][j]=='*' )
 50                 A[i][q] |= ((1LL)<<(j-1));
 51         }
 52     }
 53     for( int i=1;i<=n;i++ ){
 54         for( int j=q+1;j<=m;j++ ){
 55             if( mat[i][j-q]=='*' ) A[i][j] = A[i][j-1]-(1LL);
 56             else A[i][j] = A[i][j-1];
 57             A[i][j] = A[i][j]>>(1LL);
 58             if( mat[i][j]=='*' )
 59                 A[i][j] |= ((1LL)<<(q-1));
 60         }
 61     }
 62 }
 63 
 64 void GetBinary( int p,int q ){
 65     for( int i=1;i<=p;i++ ){
 66         AA[ i ] = 0;
 67         for( int j=1;j<=q;j++ ){
 68             if( tmp[i][j]=='*' )
 69                 AA[ i ] |= ((1LL)<<(j-1));
 70         }
 71     }
 72 }
 73         
 74 int Judge( int n,int m,int p,int q,int64 cnt ){
 75     for( int i=1;i+p-1<=n;i++ ){
 76         if( sum[n][m]-sum[i-1][m]<cnt ) break;
 77         for( int j=q;j<=m;j++ ){
 78             bool f = true;
 79             for( int k=1;k<=p;k++ ){
 80                 if( AA[k]!=A[i+k-1][j] ){
 81                     f = false;
 82                     break;
 83                 }
 84             }
 85             if( f==true ) return 1;
 86         }
 87     }
 88     return 0;
 89 }
 90         
 91 int main(){
 92     int n,m,t,p,q;
 93     int Case = 1;
 94     while( scanf("%d%d%d%d%d",&n,&m,&t,&p,&q)==5 ){
 95         if( n+m+t+p+q==0 ) break;
 96         for( int i=1;i<=n;i++ ){
 97             scanf("%s",mat[i]+1);
 98         }
 99         init( n,m,p,q );
100         int ans = 0;
101         while( t-- ){
102             int64 cnt = 0;
103             for( int i=1;i<=p;i++ ){
104                 scanf("%s",tmp[i]+1);
105                 for( int j=1;j<=q;j++ ){
106                     if( tmp[i][j]=='*' )
107                         cnt++;
108                 }
109             }
110             GetBinary( p,q );
111             ans += Judge( n,m,p,q,cnt );
112         }
113         printf("Case %d: ",Case++);
114         printf("%d\n",ans);
115     }
116     return 0;
117 }
View Code

 

posted @ 2013-08-21 15:32  xxx0624  阅读(353)  评论(0编辑  收藏  举报