ZOJ 3817 Chinese Knot

题意:给定4个长度为N的字符串( N <= 100000),然后构成一个“中国结”,给定目标串,问能否从某个节点出发走一遍得到目标串,其中不能连续通过3个中心节点,也就是从字符串一个端点转移到其他端点后必须沿着这条字符串走。

分析:对4个字符串正反两面和目标串建立相应hash函数,然后暴力枚举每一个位置出发就可以了,可以有正反两个方向的走法。中间注意一下细节差不多就可以了。

ZOJ 3817 Chinese Knot_第1张图片

代码:

  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 }
View Code

 

你可能感兴趣的:(chinese)