首页 > 代码库 > ZOJ 3817 Chinese Knot

ZOJ 3817 Chinese Knot

题意:给定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                 else125                 {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         else137         {138             puts("No solution!");139         }140     }141     return 0;142 }
View Code

 

ZOJ 3817 Chinese Knot