傳送門
這題果然是AC自動機的大好題!
題目的大意是,給定一個l*c的大網格,每個格子里有一個字符,每個格子可以向八個方向形成字符串,問給定的字符串在哪里能被匹配以及在網格中出現的方向(A代表北,然后依次順時針轉)
解題思路還好想,而且特別暴力:把給定的字符串建成一個AC自動機,之后對于大網格,把八個方向上所能形成的每一個串(一行,列,對角線)都視為文本串放進去匹配,然后記錄一下匹配到的位置。
然而聽著你就不想寫對不對?!
不過其實還好,把AC自動機建出來之后,我們沒必要寫8種情況,我們開一個像寬搜一樣記錄當前方向下一步與當前值的橫縱坐標之差,之后我們在匹配的時候,我們把起始點的坐標和匹配方向傳入,在里面像bfs一樣一直往下匹配,匹配到了就把答案記錄一下。
傳入起始點的話我們需要枚舉每一個邊上的點,枚舉每一個方向。
還有就是這個題的數據范圍明顯曖昧不清,都不告訴單詞有多長,一開始我數組開小RE了,然后調大(大概600000)才過的。
我不會告訴你我一開始沒搜出來是因為方向寫反了
代碼其實不長,真的,才120行。
?
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<set> #include<vector> #include<queue> #define pb push_back #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar('\n')using namespace std; typedef long long ll; const int M = 40005; const int N = 600005; const ll mod = 1000000007;int read() {int ans = 0,op = 1;char ch = getchar();while(ch < '0' || ch > '9'){if(ch == '-') op = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){ans *= 10;ans += ch - '0';ch = getchar();}return ans * op; }queue <int> q;struct ans {int id,x,y,fx,fy,nd;char di; }a[1005];char s[1005][1005],b[1005]; int l,C,w,dx[9] = {0,-1,-1,0,1,1,1,0,-1},dy[9] = {0,0,1,1,1,0,-1,-1,-1};struct ACG {int c[N][26],val[N],id[N],cnt,fail[N],le[N];void insert(char *p,int d){int l = strlen(p),u = 0;rep(i,0,l-1){int v = p[i] - 'A';if(!c[u][v]) c[u][v] = ++cnt;u = c[u][v];}val[u]++,id[u] = d,le[u] = l-1;}void getfail(){rep(i,0,25) if(c[0][i]) fail[c[0][i]] = 0,q.push(c[0][i]);while(!q.empty()){int k = q.front();q.pop();rep(i,0,25){if(c[k][i]) fail[c[k][i]] = c[fail[k]][i],q.push(c[k][i]);else c[k][i] = c[fail[k]][i];}}}void query(int posx,int posy,int dir){int kx = posx,ky = posy,u = 0;while(1){int v = s[kx][ky] - 'A';u = c[u][v];for(int t = u;t && val[t] != -1;t = fail[t]){if(val[t]){int px = kx - le[t] * dx[dir],py = ky - le[t] * dy[dir];a[id[t]].x = px,a[id[t]].y = py,a[id[t]].di = dir + 'A' - 1;a[id[t]].fx = posx,a[id[t]].fy = posy,a[id[t]].nd = dir;val[t] = -1;}}kx += dx[dir],ky += dy[dir];if(kx < 0 || kx > l-1 || ky < 0 || ky > C-1) break;}} }AC; int main() {l = read(),C = read(),w = read();rep(i,0,l-1) scanf("%s",s[i]);rep(i,1,w) scanf("%s",b),AC.insert(b,i);AC.getfail();rep(i,0,l-1){AC.query(i,0,3),AC.query(i,C-1,7);//k = 0AC.query(i,0,2),AC.query(i,C-1,6);//k = 1AC.query(i,0,4),AC.query(i,C-1,8);//k = -1 }rep(i,0,C-1){AC.query(0,i,5),AC.query(l-1,i,1);//k = INFAC.query(0,i,6),AC.query(l-1,i,2);//k = 1AC.query(0,i,4),AC.query(l-1,i,8);//k = -1 }rep(i,1,w) printf("%d %d %c\n",a[i].x,a[i].y,a[i].di);//%d %d %d\n",a[i].x,a[i].y,a[i].di,a[i].fx,a[i].fy,a[i].nd);return 0; }
?