对四个串的正反进行哈希,暴力枚举起点,dfs判是否可行。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<ostream>
#include<istream>
#include<algorithm>
#include<queue>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define inf (1<<30)
#define eps 1e-8
#define pb push_back
using namespace std;
const int maxn=110005;
const ull seed=131;
ull P[maxn];
char s[4][2][maxn];
char text[maxn];
ull Hash[4][2][maxn];
ull ha[maxn];
int n,m;
vector<int>path;
void pre()
{
P[0]=1;
for(int i=1;i<=100000;i++)
P[i]=P[i-1]*seed;
}
void haha()
{
for(int i=0;i<4;i++) {
for(int j=0;j<2;j++) {
Hash[i][j][0]=1;
for(int k=1;k<=n;k++)
Hash[i][j][k]=Hash[i][j][k-1]*seed+s[i][j][k];
}
}
ha[0]=1;
for(int i=1;i<=m;i++)
ha[i]=ha[i-1]*seed+text[i];
}
bool check(int a,int b,int c,int d,int e,int f)
{
ull p1=Hash[a][b][d]-Hash[a][b][c-1]*P[d-c+1];
ull p2=ha[f]-ha[e-1]*P[f-e+1];
if(p1==p2)
return true;
return false;
}
bool dfs(int a,int b,int c,int d)
{
if(m-d+1<=n-c+1) {
int l=m-d+1;
if(!check(a,b,c,c+l-1,d,m))
return false;
if(b==0) {
int o=a*n+c;
o+=m-d+1; o--;
for(int f=0;f<m-d+1;f++,o--)
path.pb(o);
}
else {
int o=a*n+(n-c+1);
o-=m-d+1; o++;
for(int f=0;f<m-d+1;f++,o++)
path.pb(o);
}
return true;
}
int l=n-c+1;
if(!check(a,b,c,n,d,d+l-1))
return false;
for(int i=0;i<4;i++) {
for(int j=0;j<2;j++) {
if(i==a && j==(!b))
continue;
if(dfs(i,j,1,d+l)) {
if(b==0) {
int o=a*n+c;
o+=n-c+1; o--;
for(int f=0;f<n-c+1;f++,o--)
path.pb(o);
}
else {
int o=a*n+(n-c+1);
o-=n-c+1; o++;
for(int f=0;f<n-c+1;f++,o++)
path.pb(o);
}
return true;
}
}
}
return false;
}
bool solve()
{
for(int i=0;i<4;i++) {
for(int j=0;j<2;j++) {
for(int k=1;k<=n;k++) {
if(dfs(i,j,k,1)) {
return true;
}
}
}
}
return false;
}
int main()
{
pre();
int t;
scanf("%d",&t);
while(t--) {
path.clear();
scanf("%d%d",&n,&m);
for(int i=0;i<4;i++) {
scanf("%s",s[i][0]+1);
strcpy(s[i][1]+1,s[i][0]+1);
reverse(s[i][1]+1,s[i][1]+n+1);
}
scanf("%s",text+1);
haha();
if(solve()) {
for(int i=path.size()-1;i>=0;i--) {
if(i==0)
printf("%d\n",path[i]);
else
printf("%d ",path[i]);
}
}
else
printf("No solution!\n");
}
return 0;
}
656

被折叠的 条评论
为什么被折叠?



