您的位置:首页 > 产品设计 > UI/UE

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 MB
Submit: 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_zzuspy
2
orz
us
YM_2030xxj
3_20
03
M_

Sample Output

6 1
5 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: