A2. Death Stars (medium)【字符串hash+KMP】

time limit per test
2.5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

The stardate is 1983, and Princess Heidi is getting better at detecting the Death Stars. This time, two Rebel spies have yet again given Heidi two maps with the possible locations of the Death Star. Since she got rid of all double agents last time, she knows that both maps are correct, and indeed show the map of the solar system that contains the Death Star. However, this time the Empire has hidden the Death Star very well, and Heidi needs to find a place that appears on both maps in order to detect the Death Star.

The first map is an N × M grid, each cell of which shows some type of cosmic object that is present in the corresponding quadrant of space. The second map is an M × N grid. Heidi needs to align those two maps in such a way that they overlap over some M × M section in which all cosmic objects are identical. Help Heidi by identifying where such an M × M section lies within both maps.

Input

The first line of the input contains two space-separated integers N and M (1 ≤ N ≤ 2000, 1 ≤ M ≤ 200, M ≤ N). The next N lines each contain M lower-case Latin characters (a-z), denoting the first map. Different characters correspond to different cosmic object types. The next M lines each contain N characters, describing the second map in the same format.

Output

The only line of the output should contain two space-separated integers i and j, denoting that the section of size M × M in the first map that starts at the i-th row is equal to the section of the second map that starts at the j-th column. Rows and columns are numbered starting from 1.

If there are several possible ways to align the maps, Heidi will be satisfied with any of those. It is guaranteed that a solution exists.

Example
input
Copy
10 5
somer
andom
noise
mayth
eforc
ebewi
thyou
hctwo
again
noise
somermayth
andomeforc
noiseebewi
againthyou
noisehctwo
output
Copy
4 6
Note

The 5-by-5 grid for the first test case looks like this:


mayth
eforc
ebewi
thyou
hctwo

 题目大意:

给一个n*m的字符矩阵

再给一个m*n的字符矩阵(n>=m)

要求找到一个第一个字符矩阵的一个m*m的子矩阵,使其在第二个m*n的矩阵中也出现过

方法:

先字符串hash,求得第一个矩阵中任意一列任意一短行宽为m的字符串的hash值,使其作为匹配串。

第二个矩阵的每一列的hash值作为主串,进行匹配。

若匹配成功则得到答案。

若失败,继续枚举第一个矩阵的下一行。

 1 #include<iostream>
 2 using namespace std;
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<map>
 6 typedef unsigned long long ull;
 7 char S[3000][300];
 8 char M[300][3000];
 9 ull hS[3000][300];
10 ull hM[300][3000];
11 ull seed = 13331;
12 ull tS[3000];
13 ull p[30000];
14 ull tM[3000];
15 unsigned long long* Getnext(ull *p,int len_p){//p为模式串 
16     unsigned long long *Next = new unsigned long long[len_p+10];
17     Next[0] = -1;
18     int j = -1,i=0;
19     while(i < len_p){//自身与自身匹配 
20         while(j != -1&&p[j]!=p[i])//移动匹配串 
21             j = Next[j];
22         j+=1;
23         Next[++i] = j; 
24     }
25     return Next;
26 }
27 int Kmp(unsigned long long *s,unsigned long long *p,int len_s,int len_p){//s为主串,p为匹配串 
28     unsigned long long *Next = Getnext(p,len_p);//求得Next数组    
29     int j = 0;//j为匹配串匹配到的位置 
30     for(int i=0;i < len_s;i++){
31         while(j != -1 && s[i] != p[j])
32             j = Next[j];
33         j+=1;
34         if(j == len_p){//匹配串匹配完毕
35             return i+1-len_p;
36             j = Next[j];//j退回到Next[j] 
37         }
38     } 
39     delete []Next;
40     return -1;
41 }
42 int main(){
43     int n,m;
44     p[0]=1;
45     memset(hS,0,sizeof(hS));
46     memset(hM,0,sizeof(hM));
47     for (int i=1;i<30000;i++){
48         p[i]=p[i-1]*seed;
49     }
50     scanf("%d%d",&n,&m);
51     for(int i=1;i<=n;i++)
52         scanf("%s",S[i]+1);
53     for(int i=1;i<=m;i++)
54         scanf("%s",M[i]+1);
55     for(int i=1;i<=n;i++){
56         for(int j=1;j<=m;j++){
57             hS[i][j] = hS[i-1][j] * seed + S[i][j] - '0';
58         }
59     }
60     for(int i=1;i<=n;i++){
61         hM[0][i] = 0;
62         for(int j=1;j<=m;j++){
63             hM[j][i] = hM[j-1][i]*seed + M[j][i] - '0';
64         }
65         tM[i-1] = hM[m][i];
66     }
67     int zans = 0;
68     int x,y;
69     for(int i=m;i<=n;i++){
70         for(int j=1;j<=m;j++){
71             tS[j] = hS[i][j] - hS[i-m][j]*p[m];
72         }
73         for(int j=0;j<m;j++){
74             tS[j] = tS[j+1];
75         }
76         tS[m] = 0;
77         int ans=Kmp(tM,tS,n,m);
78         if(ans<0)
79             continue;
80         zans = 1;
81         x = i-m+1;
82         y = ans+1;
83         break;
84     }
85     printf("%d %d",x,y);
86     return 0;
87 }

猜你喜欢

转载自www.cnblogs.com/xfww/p/8835375.html