西电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]='';
        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了。。。

没有AC不了的题,只有不努力的ACMER!
原文地址:https://www.cnblogs.com/--560/p/4500819.html