西电oj1037 字符串
1037: 倍流畅序列
时间限制: 1 Sec 内存限制: 128 MB提交: 34 解决: 9
[提交][状态][讨论版]
题目描述
对于一个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
思路:看起来是匹配,实际上是个水题。。。连c语言字符串的基础题都不能秒,真是惭愧。。。
把输进去的字符串逆转得到取反得到新串,两个串慢慢错位匹配重叠部分,如果重叠部分匹配,前后部分直接补充就行了,如下图:
100 --> 100 --> 100 --> 100 ---> 100110
110 110 110 110 100110
0011
0011
010 --> 010 --> 0101
101 101 0101
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/** 上面的对齐真是不忍吐槽了。。。 下面这个看得比较清楚: 100 --> 100 --> 100 --> 100 --> 100110 110 110 110 100 100110 0101 0101 010 --> 010 --> 0101 101 101 0101 */ #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int maxn=1000100; const int INF=(1<<29); char s[maxn],t[maxn]; int main() { int T;cin>>T; while(T--){ scanf("%s",s); int len=strlen(s); for(int i=0;i<len;i++){ if(s[i]=='1') t[len-1-i]='0'; else t[len-1-i]='1'; } t[len]='\0'; int res=len; for(int i=0;i<len;i++){ if(strncmp(s+i,t,len-i)==0){ res=i;break; } } strcat(s,t+(len-res)); puts(s); } return 0; }
================================================================================================
注意,strcmp是o(n)的,所以,这真的是个匹配的题啊。。。
如果把长度改为1e-6就得用KMP了,看来这几天得学KMP了。。。