XDU-1037 倍流畅序列 (贪心)

1037: 倍流畅序列

时间限制:  1 Sec   内存限制:  128 MB
http://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;
}


你可能感兴趣的:(贪心,xdu)