题意:给定4个长度为N的字符串( N <= 100000),然后构成一个“中国结”,给定目标串,问能否从某个节点出发走一遍得到目标串,其中不能连续通过3个中心节点,也就是从字符串一个端点转移到其他端点后必须沿着这条字符串走。
分析:对4个字符串正反两面和目标串建立相应hash函数,然后暴力枚举每一个位置出发就可以了,可以有正反两个方向的走法。中间注意一下细节差不多就可以了。
代码:
1 #include <bits/stdc++.h> 2 #pragma comment(linker, "/STACK:102400000,102400000") 3 #define in freopen("F:\\rootial\\data\\data.txt", "r", stdin); 4 #define bug(x) printf("Line %d: >>>>>>\n", (x)); 5 #define pb push_back 6 #define mp make_pair 7 8 using namespace std; 9 typedef long long LL; 10 typedef unsigned long long ULL; 11 typedef pair<int, int> PII; 12 typedef vector<pair<int, int > > VII; 13 14 const ULL seed = 107; 15 16 const int maxn = 100000 + 100; 17 char s[4][maxn], ta[maxn]; 18 ULL hh[12][maxn], tt[maxn], HH[maxn]; 19 void pre() 20 { 21 tt[0] = 1; 22 for(int i = 1; i < maxn; i++) 23 tt[i] = tt[i-1]*seed; 24 } 25 int n, m; 26 VII ans; 27 bool dfs(int x, int pos, int dir, int len) 28 { 29 if(len == 0) 30 return true; 31 int len1 = n-pos+1; 32 int mlen = min(len, len1); 33 int ok = 0; 34 if(hh[x<<1|dir][pos]-hh[x<<1|dir][pos+mlen]*tt[mlen] == HH[m-len+1]-HH[m-len+mlen+1]*tt[mlen]) 35 { 36 ok = 1; 37 ans.pb(mp(x*n+(dir ? n+1-pos : pos), dir)); 38 len -= mlen; 39 if(len == 0) 40 return true; 41 for(int k = 0; k < 4; k++) 42 for(int j = 0; j < 2; j++) 43 { 44 if(k == x && (j^1) == dir) 45 continue; 46 if(dfs(k, 1, j, len)) 47 return true; 48 } 49 } 50 if(ok) 51 ans.pop_back(); 52 return false; 53 } 54 int main() 55 { 56 57 pre(); 58 int T; 59 for(int t(scanf("%d", &T)); t <= T; t++) 60 { 61 scanf("%d%d", &n, &m); 62 for(int i = 0; i < 4; i++) 63 scanf("%s", s[i]+1); 64 scanf("%s", ta+1); 65 for(int i = 0; i < 8; i++) 66 hh[i][n+1] = 0; 67 HH[m+1] = 0; 68 for(int i = 0; i < 4; i++) 69 { 70 for(int j = n; j >= 1; j--) 71 { 72 hh[i<<1][j] = hh[i<<1][j+1]*seed+(s[i][j]-'a'); 73 hh[i<<1|1][j] = hh[i<<1|1][j+1]*seed+(s[i][n+1-j]-'a'); 74 } 75 } 76 for(int i = m; i >= 1; i--) 77 { 78 HH[i] = HH[i+1]*seed+(ta[i]-'a'); 79 } 80 int ok = 0; 81 for(int k = 0; k < 4; k++) 82 { 83 for(int pos = 1; pos <= n; pos++) 84 { 85 for(int j = 0; j < 2; j++) 86 { 87 ok = 0; 88 ans.clear(); 89 if(dfs(k, pos, j, m)) 90 { 91 ok = 1; 92 break; 93 } 94 if(ok) 95 break; 96 } 97 if(ok) 98 break; 99 } 100 if(ok) 101 { 102 break; 103 } 104 } 105 int ll = 0; 106 if(ok) 107 { 108 for(int i = 0; i < ans.size(); i++) 109 { 110 PII x = ans[i]; 111 int st = x.first; 112 int dir = x.second; 113 int k = (st-1)/n+1; 114 115 if(dir == 0) 116 { 117 for(int j = st; j <= k*n && ll < m; j++, ll++) 118 { 119 if(ll) 120 putchar(' '); 121 printf("%d", j); 122 } 123 } 124 else 125 { 126 for(int j = st; j > (k-1)*n && ll < m; j--, ll++) 127 { 128 if(ll) 129 putchar(' '); 130 printf("%d", j); 131 } 132 } 133 } 134 cout<<endl; 135 } 136 else 137 { 138 puts("No solution!"); 139 } 140 } 141 return 0; 142 }