zzulioj 1818: squee_spoon and his Cube VI 【dp】
2015-12-09 17:06
489 查看
1818: squee_spoon and his Cube VI
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 58 Solved: 14
SubmitStatusWeb
Board
Description
市面上最常见的魔方,是三阶魔方,英文名为Rubik's Cube,以魔方的发明者鲁比克教授的名字命名。另外,二阶魔方叫Pocket Cube,它只有2*2*2个角块,通常也就比较小;四阶魔方叫Revenge Cube,这是因为就算你好不容易复原了三阶魔方,四阶魔方也会向你“复仇”;而五阶魔方叫Professor Cube,人们认为只有专家才能够复原这么复杂的魔方。作为ACM(A Cube Master),squee_spoon准备为九阶正十二面体魔方命名,此时他的脑中浮现出一个长长的字符串S,似乎可以作为魔方的英文名。但是问题没有那么简单,squee_spoon有n个不喜欢的短字符串a1~an,所以squee_spoon希望将九阶正十二面体魔方命名为S的最长子串T,在这个子串中,不能包含a1~an,即a1~an均不是T的子串。
Input
多组数据。第一行,字符串S,长度不会超过10^5。
第二行,一个整数n,1<=n<=10。
接下来的n行,n个字符串a1~an,ai的长度不会超过10。
Output
对于每组数据,输出两个整数,分别是T的长度及其在原串S中的起始下标(下标从0开始,如果存在多解,输出最小的起始下标)。Sample Input
orz_zzuspy2
orz
us
YM_2030xxj
3_20
03
M_
Sample Output
6 15 5
醉了,用gets(str) WA了一晚上,换了scanf()就过了。有毒。。。
思路:设置dp[i]的状态,表示以str[i]结尾的合法子串,我们只需维护子串的长度和起点即可。
一、dp[i-1].len == 0,表示以str[i]结尾的合法子串不存在,我们只需要判定str[i]是否合法。
二、dp[i-1].len != 0,表示以str[i]结尾的合法子串存在,我们需要添加字符str[i]构成新串ss。然后判断ss是否包含这n个子串,若不包含任意一个则更新dp[i]长度 = dp[i-1]长度 + 1, 起点为dp[i-1]的起点。反之,找到最短的子串,返回下标op,我们维护的dp[i]的长度 = 第op个子串的长度-1。
最后扫一遍就ok了。
AC代码:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #define INF 0x3f3f3f #define eps 1e-8 #define MAXN (500000+10) #define MAXM (100000) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while(a--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 using namespace std; char str[MAXN], ss[MAXN], a[20][20]; int judge(int s, int t, int n) { int top = 0; for(int i = s; i <= t; i++) ss[top++] = str[i]; ss[top] = '\0'; int mark = -1, len = INF; for(int i = 0; i < n; i++) if(strstr(ss, a[i]) && strlen(a[i]) < len) mark = i, len = strlen(a[i]); return mark; } struct Node{ int len, id; }; Node dp[MAXN]; int main() { while(scanf("%s", str) != EOF) { int n; Ri(n); //getchar(); for(int i = 0; i < n; i++) scanf("%s", a[i]); int len = strlen(str); int k = 0; if(judge(0, 0, n) == -1) dp[0].len = 1, dp[0].id = 0; else dp[0].len = 0; //printf("%d %d\n", dp[0].len, dp[0].id); for(int i = 1; i < len; i++) { int op; if(dp[i-1].len == 0) { op = judge(i, i, n); if(op == -1) dp[i].len = 1, dp[i].id = i; else dp[i].len = 0; continue; } op = judge(dp[i-1].id, i, n); if(op == -1) { dp[i].len = dp[i-1].len + 1; dp[i].id = dp[i-1].id; } else { int temp = strlen(a[op]); if(temp == 1) dp[i].len = 0; else { dp[i].len = strlen(a[op]) - 1; dp[i].id = i - dp[i].len + 1; } } //printf("%d %d\n", dp[i].len, dp[i].id); } int ans = 0, mark = 0; for(int i = 0; i < len; i++) { if(dp[i].len > ans || (dp[i].len == ans && dp[i].id < mark)) { ans = dp[i].len; mark = dp[i].id; } } printf("%d %d\n", ans, mark); } return 0; }
相关文章推荐
- Android开发之浅仿QQ聊天UI和键盘控制
- 'Building workspace' has encountered a problem.
- Java GUI 小程序 任意圆之间的带箭头的连线并可以存储
- hdu 5312 Sequence(数学推导——三角形数)
- iOS 扩展 UINavigationController 出栈返回到先前标记的位置
- VS2015 build kmdf for Window 8.1
- Arduino - DHT11温湿度传感器
- EasyUi我引入的不对吗?为什么没有任何反应?
- Android下uid与多用户释疑(一)
- marquee 轮播滚动吧span、img、div!!
- IOS-开发日记24 - UITableViewCell点击两次才跳转解决办法
- android Installation failed due to invalid URI! 错误处理
- Android之UID and PID
- 点击Cell的时候 出现一个 小对勾的( 确定UITableViewCell AccessoryCheckmark唯一性)
- iOS 从各种效果图颜色标注生成 UIColor
- IntelliJ IDEA的jsp中request等对象无法被解析的解决办法
- squee_spoon and his Cube VI---郑大校赛(求最长子串)
- easyui ValidateBox validType字段设置多个校验规则
- android 事件处理机制之requestDisallowInterceptTouchEvent
- iOS系列UI篇——UIImageView