单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at和atide间不能相连。
标签:
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at和atide间不能相连。
第1行为一个单独的整数n(n≤20),表示单词数,以下n行每行有一个单词,输入的最后1行为一个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。
输出以此字母开头的最长的“龙”的长度。
5
at
touch
cheat
choose
tact
a
23
样例说明:连成的“龙”为atoucheatactactouchoose。
分析:dfs暴搜,注意每个单词可以出现2次;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <queue> #include <stack> #include <vector> #include <list> #include <ext/rope> #define rep(i,m,n) for(i=m;i<=n;i++) #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++) #define vi vector<int> #define pii pair<int,int> #define mod 1000000007 #define inf 0x3f3f3f3f #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) const int maxn=1e2+10; const int dis[4][2]={{0,1},{-1,0},{0,-1},{1,0}}; using namespace std; using namespace __gnu_cxx; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} int n,m,p[maxn]={0},ma; string a[maxn]; char b; void dfs(string q,int cnt,int p[]) { ma=max(ma,cnt); int len=q.length(); for(int i=0;i<2*n;i++) { if(!p[i]) { int len2=a[i].length(); int len1=min(len2,len); for(int j=1;j<=len1-1;j++) { if(q.substr(len-j,j)==a[i].substr(0,j)) { p[i]=1; dfs(a[i],cnt+a[i].length()-j,p); p[i]=0; goto loop; } } } loop:; } } int main() { int i,j,k,t; scanf("%d",&n); rep(i,0,n-1)cin>>a[i],a[n+i]=a[i]; cin>>b; rep(i,0,n-1)if(a[i][0]==b)p[i]=1,dfs(a[i],a[i].length(),p),p[i]=0; printf("%d\n",ma); //system ("pause"); return 0; }
标签:
原文地址:http://www.cnblogs.com/dyzll/p/5720570.html