NOIP2000提高组复赛C 单词接龙

题目链接:https://ac.nowcoder.com/acm/contest/248/C

题目大意:

  略

分析:

  注意点:1.前缀和后缀的公共部分应该选最短的。2.如果两个字符串前缀和后缀的公共部分恰好是其中一个字符串,那么这两个字符串不能合并。

代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 #define rep(i,n) for (int i = 0; i < (n); ++i)
 5 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
 6 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
 7 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
 8 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
 9  
10 #define pr(x) cout << #x << " = " << x << "  "
11 #define prln(x) cout << #x << " = " << x << endl
12  
13 #define ALL(x) x.begin(),x.end()
14 #define INS(x) inserter(x,x.begin())
15  
16 #define ms0(a) memset(a,0,sizeof(a))
17 #define msI(a) memset(a,inf,sizeof(a))
18  
19 #define pii pair<int,int>
20 #define piii pair<pair<int,int>,int>
21 #define mp make_pair
22 #define pb push_back
23 #define fi first
24 #define se second
25  
26 inline int gc(){
27     static const int BUF = 1e7;
28     static char buf[BUF], *bg = buf + BUF, *ed = bg;
29      
30     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
31     return *bg++;
32 }
33  
34 inline int ri(){
35     int x = 0, f = 1, c = gc();
36     for(; c<48||c>57; f = c=='-'?-1:f, c=gc());
37     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
38     return x*f;
39 }
40  
41 typedef long long LL;
42 const int maxN = 1e5 + 7;
43  
44 int n, ans;
45 string str[21];
46 vector< pii > nexts[21];
47 int cnt[21];
48 string st;
49  
50 // Common prefix and suffix
51 int CPS(int x, int y) {
52     int ret = 0, i = str[x].size()-1, j = 1;
53      
54     while(i >= 0 && j < str[y].size()){
55         if(str[x].substr(i, str[x].size()) == str[y].substr(0, j)) {
56             ret = j;
57             break;
58         }
59         --i;
60         ++j;
61     }
62     if(ret == str[x].size() || ret == str[y].size()) ret = 0;
63     return ret;
64 }
65  
66 void dfs(int x, int ret) {
67     bool flag = true;
68     rep(i, nexts[x].size()) {
69         int nt = nexts[x][i].se;
70         if(cnt[nt] >= 2) continue;
71         flag = false;
72          
73         ++cnt[nt];
74          
75         dfs(nt, ret + str[nt].size() - nexts[x][i].fi);
76          
77         --cnt[nt];
78     }
79     if(flag) ans = max(ans, ret);
80 }
81  
82 int main(){
83     scanf("%d", &n);
84     For(i, 1, n) cin >> str[i];
85     cin >> st;
86     For(i, 1, n) {
87         For(j, 1, n) {
88             int t = CPS(i, j);
89             if(t) nexts[i].push_back(mp(t, j));
90         }
91     }
92     For(j, 1, n) {
93         if(st[0] == str[j][0])nexts[0].push_back(mp(0, j));
94     }
95     dfs(0, 0);
96      
97     printf("%d\n", ans);
98     return 0;
99 }
View Code

 

转载于:https://www.cnblogs.com/zaq19970105/p/10753006.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值