HDU
来源:互联网 发布:mac软件怎么卸载 编辑:程序博客网 时间:2024/06/06 12:26
点击打开题目链接
Bazinga
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 6170 Accepted Submission(s): 1902
Problem Description
Ladies and gentlemen, please sit up straight.
Don't tilt your head. I'm serious.
Forn given strings S1,S2,⋯,Sn , labelled from 1 to n , you should find the largest i (1≤i≤n) such that there exists an integer j (1≤j<i) and Sj is not a substring of Si .
A substring of a stringSi is another string that occurs in Si . For example, ``ruiz" is a substring of ``ruizhang", and ``rzhang" is not a substring of ``ruizhang".
Don't tilt your head. I'm serious.
For
A substring of a string
Input
The first line contains an integer t (1≤t≤50) which is the number of test cases.
For each test case, the first line is the positive integern (1≤n≤500) and in the following n lines list are the strings S1,S2,⋯,Sn .
All strings are given in lower-case letters and strings are no longer than2000 letters.
For each test case, the first line is the positive integer
All strings are given in lower-case letters and strings are no longer than
Output
For each test case, output the largest label you get. If it does not exist, output −1 .
Sample Input
45ababczabcabcdzabcd4youlovinyouaboutlovinyouallaboutlovinyou5dedefabcdabcdeabcdef3abaccc
Sample Output
Case #1: 4Case #2: -1Case #3: 4Case #4: 3
Source
2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)
Recommend
wange2014
题目大意:
给出n个字符串,找到最大的j使得从1->j-1中存在s[i]不是s[j]的子串。
思路:
如果直接枚举两个串复杂度为50*500*500=12500000,还不加匹配算法的复杂度,超时。
现在想可不可以剪枝。
两层循环,第一层i枚举所有子串,第二层j枚举母串。
如果s[i]是s[j]的子串,则s[i]串的贡献完全可以转化成s[j]串,则直接break到下一个子串.
如果s[i]串不是s[j]的子串,则s[j]串即为满足题目要求的,标记下来,以后遍历母串跳过s[j]即可。
然后遍历寻找最大的j即可。
KMP版代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 500 + 5;char s[maxn][2500];int t, n;int p[maxn], nxt[maxn][2500], len[maxn];void getNext(int t) { int i, j; j = nxt[t][0] = -1; i = 0; while(i < n) { while(j != -1 && s[t][i] != s[t][j]) j = nxt[t][j]; nxt[t][++i] = ++j; }}//判断s[v]是否包含s[u]int kmp(int v, int u) { int i, j; i = j = 0; while(i < len[v]) { while(j != -1 && s[v][i] != s[u][j]) j = nxt[u][j]; i++;j++; if(j >= len[u]) { return 1; } } return 0;}int solve() { memset(p,1,sizeof(p)); int ans = -1; for(int i = 1; i < n; i++) { for(int j = i + 1; j <= n; j++) { if(p[j]) { if(kmp(j, i)) break; else { p[j] = 0; ans = max(ans, j); } } } } return ans;}int main() { scanf("%d", &t); for(int kase = 0; kase < t; kase++) { scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%s", s[i]); len[i] = strlen(s[i]); getNext(i); } printf("Case #%d: %d\n",kase+1, solve()); } return 0;}
看了别人的AC,才直到有strstr函数,可以寻找s[i]在s[j]串中的位置。
strstr版代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;using namespace std;const int maxn = 500 + 5;char s[maxn][2500];int t, n;int p[maxn];int solve() { memset(p,1,sizeof(p)); int ans = -1; for(int i = 1; i < n; i++) { for(int j = i + 1; j <= n; j++) { if(p[j]) { if(strstr(s[j], s[i])) break; else { p[j] = 0; ans = max(ans, j); } } } } return ans;}int main() { scanf("%d", &t); int kase = 0; while(t--) { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%s", s[i]); printf("Case #%d: %d\n",++kase, solve()); } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- 面试中单例模式有几种写法
- windons-端口
- Linux下ps -ef和ps aux的区别
- new一个对象给我们做了什么
- Quartz实现定时任务
- HDU
- C语言从入门到精通笔记
- Android 自定义Switch开关按钮的样式
- 485. Max Consecutive Ones 找二进制数中连续1
- C# Dictionary简单介绍,单很明了
- 企业中常用的vlan划分方法
- Springboot中的test
- openvpn讲解
- 解决ubuntu删除ibus后桌面打不开的问题