1037: 倍流畅序列
时间限制: 1 Sec 内存限制: 128 MBhttp://acm.xidian.edu.cn/problem.php?id=1037
[ 提交 ][ 状态 ][ 讨论版 ]
题目描述
对于一个0、1串s, 从左端开始读取它的0获得序列s0,从右端开始读取它的1获得s1,如果s1与s2同构,则称s为倍流畅序列.
例如:
011001是一个倍流畅序列, 因为:
s0 = 0__00_
s1 = 1__11_
而101不是, 因为:
s0 = _0_
s1 = 1_1
下面的问题是:对于一个0、1串s, 在s后添加最少数目的0或1,使它成为一个倍流畅序列。
输入
有多组输入数据,第一行为一个数字T,代表有T组输入数据 (0<T<=100)。
接下来为T组数据,每组数据占一行,包含一个长度不超过50的0、1串。
输出
一共T行。
对于每组数据,在一行上输出添加了最少数目的0或1后所得到的倍流畅序列。
样例输入
3
100
0011
010
样例输出
100110
0011
0101
设原串为s,令t串为s串逆序后,再取反形成的串(例如:s:0100 -> t:1101)
这样s+t就一定是一个合法解,要想添加的字符串最少,就需要s串的后缀和t串的前缀匹配的最多,由于数据很小,所以直接从前开始枚举s串的后缀起始位置即可
#include <cstdio>
#include <cstring>
using namespace std;
int T,len,mxlcs;//mxlcs表示s串的后缀和t串的前缀的最大公共长度
char s[55],t[55];
inline bool judge(int sta) {//判断s串从sta开始的后缀是否能和t串的前缀完全匹配
for(int i=sta;i<len;++i)
if(s[i]!=t[i-sta])
return false;
return true;
}
int main() {
while(1==scanf("%d",&T)) {
while(T-->0) {
scanf("%s",s);
len=strlen(s);
for(int i=len-1;i>=0;--i)
t[len-i-1]=s[i]=='1'?'0':'1';
t[len]='\0';
mxlcs=0;//初始化为0
for(int i=0;i<len;++i) {
if(judge(i)) {//找到第一个匹配的就退出
mxlcs=len-i;
break;
}
}
printf("%s",s);
for(int i=mxlcs;i<len;++i)
printf("%c",t[i]);
printf("\n");
}
}
return 0;
}