• 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: >>>>>>
    ", (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
  • 相关阅读:
    nlogn LIS CF1437E
    CF 1444B
    unsigned int慎用
    CF1425D 容斥 组合数 快速幂求逆元
    CF 1408D探照灯 找 匪
    各种状态转移
    CF 459C
    主席树 入门
    杭州特色景致的性价比精致餐厅
    SQL函数总结
  • 原文地址:https://www.cnblogs.com/rootial/p/3960670.html
Copyright © 2020-2023  润新知