Problem L3-029 还原文件 (30 分)
应
该
算
是
一
道
模
板
题
目
了
,
字
符
串
h
a
s
h
+
d
f
s
匹
配
应该算是一道模板题目了,字符串hash+dfs匹配
应该算是一道模板题目了,字符串hash+dfs匹配
建议背下来
/*Love coding and thinking!*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <vector>
#define pb push_back
#define mem(f, x) memset(f,x,sizeof(f))
#define fo(i,a,n) for(int i=(a);i<=(n);++i)
#define fo2(i,a,n) for(int i=(a);i<(n);++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
#define endl '\n'
using namespace std;
typedef pair<int,int>PII;
typedef pair<long,long>PLL;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+10,M=110,P=131;
int n,m,_;
ull g[N],p[N];//长版的hash
ull Hash[M];//每个小长条的hash
int width[M];
int ans[M];
bool st[M];//判重数组
int x;
ull get(int l,int r)//返回区间hash值
{
return g[r]-g[l-1]*p[r-l+1];
}
bool dfs(int u,int ed)//第u个长条能不能拼接上,上一个的结尾是ed
{
if(ed==n)
{
return true;
}
for(int i=1;i<=m;i++)
{
if(!st[i]&&Hash[i]==get(ed,ed+width[i]-1))
{
st[i]=1;
ans[u]=i;
if(dfs(u+1,ed+width[i]-1))
return 1;
st[i]=0;
}
}
return false;
}
int main()
{
cin>>n;
p[0]=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
p[i]=p[i-1]*P;//只在得到区间hash值时用到
g[i]=g[i-1]*P+x+1;//一般都是*P,注意区分,因为0、00的会重复,所以从1开始
}
cin>>m;
for(int i=1;i<=m;i++)
{
scanf("%d",&width[i]);
for(int j=0;j<width[i];j++)
{
scanf("%d",&x);
Hash[i]=Hash[i]*P+x+1;
}
}
dfs(1,1);
for(int i=1;i<=m;i++)
if(i!=m)
printf("%d",ans[i]);
else
printf("%d ",ans[i]);
return 0;
}