废话:

这道题很是花了我一番功夫。首先,我不会kmp算法,还专门学了一下这个算法。其次,即使会用kmp,但是如果暴力枚举的话,还是毫无疑问会爆掉。因此在dfs的基础上加上两次剪枝解决了这道题。

题意:

我没有读题,只是队友给我解释了题意,然后我根据题意写的题。

大概意思是给n个字符串,从上到下依次标记为1——n,寻找一个标记最大的串,要求这个串满足:标记比它小的串中至少有一个不是它的子串。

输入:

第一行输入一个整型t,表示共有t组数据。

每组数据首行一个整型n,表示有n个串。

接下来n行,每行一个字符串。

输出:

输出格式为”Case #x: y”,其中x为组数,y表示串的标记。

如果存在满足条件的串,则输出这个串的标记,否则输出-1。

题解:

  1. 使用dfs,源串从标记最大的串(串n-1)开始,匹配串从比源串小的串开始,从大到小依次匹配。
  2. 如果两个串匹配,则继续匹配更小的匹配串。如果两个串不匹配,则记录不匹配的匹配串,同时比较源串和答案的大小,答案取较大值,同时执行3。如果匹配串直到匹配到标记最小的串(串0),所有串都可以和源串匹配,则执行4。
  3. 源串回溯,然后用回溯的源串和记录的匹配串进行比较,即,进行2。
  4. 当前源串不满足条件,回溯到dfs结束。
  5. 输出答案。

需要注意的有两点——

  1. 如果当前源串Aj与当前匹配串Ai不匹配,那么可知当前源串的父串Ak,即当前源串的源串,也可以直接与Ai比较,而不需要与Aj和Ai之间的串匹配,因为Al(i < l < j) 一定是Ak的子串。这点很容易证明。
  2. 如果源串Ak一直递归到最小的串A0都匹配,那么任意串Ai(0 < i <= k) 都和A0匹配,即A0是任意串Ai的子串。那么任意Ai都不可能是答案。

代码如下——

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; const int N = ; int Next[N];
char s[][N];
int t, n;
int lenS, lenT;
int ans;
int mid; //剪枝,放置某个串被多次访问 void init()
{
scanf("%d", &n);
for(int i = ; i < n; i++) scanf("%s", s[i]);
ans = -;
mid = -;
} void kmpNext(char* T) //计算Next数组
{
int i = ;
Next[] = -;
while(i < lenT)
{
int j = ;
while(T[j] == T[i])
{
Next[i] = j;
i++;
j++;
}
Next[i] = j;
i++;
}
} bool kmp(char* S, char* T) //kmp算法
{
lenS = strlen(S);
lenT = strlen(T);
kmpNext(T);
int i = , j = ;
while(i < lenS && j < lenT)
{
if(j == -)
{
i++;
j = ;
}
else if(S[i] == T[j])
{
i++;
j++;
}
else j = Next[j];
}
if(j == lenT) return ;
return ;
} bool dfs(int x) //递归寻找子串
{
for(int i = x-; i >= ; i--)
{
if(mid != - && mid != i) continue; //剪枝,如果串Ai从未查询过,或者串Ax的子串含不串Ai,那么查询Ax是否含Ai
if(kmp(s[x], s[i]))
{
if(i == ) return ;
mid = -; //如果串Ax含串Ai,那么mid归为-1
bool flag = dfs(i);
if(flag) return ; //剪枝,如果串A0是串Ax的子串,那么Ax不符合条件
}
else
{
ans = ans > x ? ans : x; //永远取最大值
mid = i;
break;
} }
return ;
} void work()
{
dfs(n-);
} void outit(int tm)
{
printf("Case #%d: %d\n", tm, ans+);
} int main()
{
scanf("%d", &t);
for(int tm = ; tm <= t; tm++)
{
init();
work();
outit(tm);
}
}

Kmp算法——

http://www.cnblogs.com/mypride/p/4950245.html

ps. 看了看别人的代码,有些直接用了迭代法,复杂度为n^2/2,不过加上了一个感觉不太靠谱的剪枝。我算了算,最坏情况下时间好像还有可能爆掉。但是运行结果竟然不比我的慢多少,醉了。可能我算时间的方法有问题?或者数据特殊?

唉……革命尚未成功,同志仍需努力啊!

hdu 5510 Bazinga (kmp+dfs剪枝) 2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)的更多相关文章

  1. HDU 6225.Little Boxes-大数加法 (2017ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学))

    整理代码... Little Boxes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/O ...

  2. 2015ACM/ICPC亚洲区沈阳站-重现赛 B - Bazinga (KMP)

    题意:给你\(n\)个字符串,\(s_1,s_2,...,s_n\),对于\(i(1\le i\le n)\),找到最大的\(i\),并且满足\(s_j(1\le j<i)\)不是\(s_i\) ...

  3. 2015ACM/ICPC亚洲区沈阳站重现赛-HDU5512-Pagodas-gcd

    n pagodas were standing erect in Hong Jue Si between the Niushou Mountain and the Yuntai Mountain, l ...

  4. 2015ACM/ICPC亚洲区沈阳站-重现赛 M - Meeting (特殊建边,最短路)

    题意:有\(n\)个点,\(m\)个集合,集合\(E_i\)中的点都与集合中的其它点有一条边权为\(t_i\)的边,现在问第\(1\)个点和第\(n\)个点到某个点的路径最短,输出最短路径和目标点,如 ...

  5. 2015ACM/ICPC亚洲区沈阳站-重现赛 D - Pagodas

    题意:有\(n\)个数,开始给你两个数\(a\)和\(b\),每次找一个没出现过的数\(i\),要求满足\(i=j+k\)或\(i=j-k\),当某个人没有数可以选的时候判他输,问谁赢. 题解:对于\ ...

  6. HDU 6227.Rabbits-规律 (2017ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学))

    Rabbits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total S ...

  7. 2016ACM/ICPC亚洲区沈阳站-重现赛赛题

    今天做的沈阳站重现赛,自己还是太水,只做出两道签到题,另外两道看懂题意了,但是也没能做出来. 1. Thickest Burger Time Limit: 2000/1000 MS (Java/Oth ...

  8. 2017ACM/ICPC亚洲区沈阳站-重现赛

    HDU 6222 Heron and His Triangle 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6222 思路: 打表找规律+大数运算 首先我 ...

  9. 2016ACM/ICPC亚洲区沈阳站-重现赛

    C.Recursive sequence 求ans(x),ans(1)=a,ans(2)=b,ans(n)=ans(n-2)*2+ans(n-1)+n^4 如果直接就去解...很难,毕竟不是那种可以直 ...

随机推荐

  1. 使用XShell工具密钥认证登录Linux系统

    如果你是一名Linux运维,那么Linux服务器的系统安全问题,可能是你要考虑的,而系统登录方式有两种,密码和密钥.哪一种更加安全呢? 无疑是后者! 这里我为大家分享用Xshell利器使用密钥的方式登 ...

  2. iOS 开发--多线程

    前面在<Bison眼中的iOS开发多线程是这样的(二)>一文中讲完了多线程的NSThread,不难发现这种方式的多线程实现起来非常的复杂,为了简化多线程的开发,iOS提供了GCD来实现多线 ...

  3. Photoshop支持ico输出

    1.Photoshop支持ico格式插件下载:ICOFormat.8bi 2.把文件放到ps安装目录:xxx/Plug-ins/File Formats 下 3.重启下ps

  4. Java:IO流与IO设备

    打印流:PrintWriter和PrintStream 特点:可以直接操作输入流和文件 //例子1:使用PrintStream将格式化的日期打印到文件中 import java.io.*; impor ...

  5. adb 安卓opencv manager报错:adb server is out of date.killing

    原因:ref:http://jingyan.baidu.com/article/d621e8da0dee022865913fce.html      最后发现360mobil.exe占用 5037 通 ...

  6. Ext.grid.plugin.RowExpander的简单用法

    有时候,我们在grid里渲染数据时,由于某些字段的内容太长,而grid又不会自动出现滚动条,于是溢出的内容后面就会出现省略号, 导致信息展示不完全.如果,这个信息不太重要,展示不完全也无关紧要.可是, ...

  7. Docker+K8S实践

    一.运维角度: (一)镜像: 1. 避免依赖过深.不要在基础镜像上加太多产生其他的镜像,我觉得这块最多是三四层. 一层是base景像再往上是工具.中间件这样的,再往上一层就是你自己的程序,再多就比较乱 ...

  8. 深入理解Java内存模型(六)——final

    与前面介绍的锁和volatile相比较,对final域的读和写更像是普通的变量访问.对于final域,编译器和处理器要遵守两个重排序规则: 在构造函数内对一个final域的写入,与随后把这个被构造对象 ...

  9. python之for学习

    for i in range(100,-1,-1): print "%s\n"%i; import os   path = 'D:\\Test'        for root, ...

  10. Win7平台下Cocos2d-x环境搭建

    一.Win7下Cocos2d-x环境搭建 Cocos开发者平台官网——在这里下载游戏引擎           解压放到某个目录下即可 https://www.python.org/downloads/ ...