您的位置:首页 > 大数据 > 人工智能

GYM 100030 F. Magic Chains(hash+bfs)

2017-03-05 13:56 351 查看
Description

给出n个长度相同的字符串,对应位置只相差一个字母的字符串可以互通,距离为1,问第一个字符串和第n个字符串是否互通,如果互通则输出最短路径,否则输出FALL

Input

第一行一整数n表示字符串数量,之后n个长度不超过10的长度相等的只由小写字母组成的字符串(2<=n<=60000)

Output

如果第一个和最后一个字符串互通则输出最短路径,否则输出FALL

Sample Input

7

voda

yoda

vina

boda

vona

beda

vino

Sample Output

4

voda

vona

vina

vino

Solution

暴力bfsT了,加个hash就行

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 66666
#define mod 10000007
int n,pre[maxn],dis[maxn],vis[maxn];
string s[maxn];
queue<int>que;
vector<int>ans;
struct edge
{
ll v;
int id,next;
}g[maxn];
int tot,head[mod];
int H[11][33];
ll p[11],a[maxn];
void init()
{
p[0]=1;
for(int i=1;i<10;i++)p[i]=p[i-1]*26ll;
for(int i=0;i<10;i++)
for(int j=0;j<26;j++)
H[i][j]=rand();
tot=0;
memset(head,-1,sizeof(head));
}
ll deal(string s)
{
ll ans=0;
for(int i=0;i<s.size();i++)ans+=p[i]*(s[i]-'a');
return ans;
}
int hash(string s)
{
int ans=0;
for(int i=0;i<s.size();i++)ans=(ans+H[i][s[i]-'a'])%mod;
return ans;
}
void add(int x)
{
int temp=hash(s[x]);
g[tot].v=a[x];
g[tot].id=x;
g[tot].next=head[temp];
head[temp]=tot++;
}
int query(int h,ll v)
{
for(int i=head[h];~i;i=g[i].next)
if(g[i].v==v)return g[i].id;
return 0;
}
void bfs()
{
while(!que.empty())que.pop();
for(int i=2;i<=n;i++)vis[i]=0,dis[i]=INF;
vis[1]=1,dis[1]=0,pre[1]=0;
que.push(1);
int len=s[1].size();
string c;
while(!que.empty())
{
int now=que.front();que.pop();
if(now==n)break;
c=s[now];
int h=hash(c);
ll v=a[now];
for(int i=0;i<len;i++)
for(int j=0;j<26;j++)
if(j+'a'!=c[i])
{
h-=H[i][c[i]-'a'],h+=H[i][j];
v-=p[i]*(c[i]-'a'),v+=p[i]*j;
int t=query(h,v);
h+=H[i][c[i]-'a'],h-=H[i][j];
v+=p[i]*(c[i]-'a'),v-=p[i]*j;
if(!t||vis[t])continue;
vis[t]=1;
que.push(t);
dis[t]=dis[now]+1;
pre[t]=now;
if(t==n)return ;
}
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
init();
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
{
cin>>s[i];
a[i]=deal(s[i]);
add(i);
}
bfs();
if(dis
==INF)printf("FAIL\n");
else
{
printf("%d\n",dis
+1);
ans.clear();
int now=n;
while(1)
{
ans.push_back(now);
now=pre[now];
if(!pre[now])break;
}
cout<<s[1]<<endl;
for(int i=ans.size()-1;i>=0;i--)cout<<s[ans[i]]<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: