西电oj1037 字符串

西电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

/**

上面的对齐真是不忍吐槽了。。。

下面这个看得比较清楚:

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;

}
View Code

 ================================================================================================

注意,strcmp是o(n)的,所以,这真的是个匹配的题啊。。。

如果把长度改为1e-6就得用KMP了,看来这几天得学KMP了。。。

你可能感兴趣的:(字符串)