• BestCoder Round #87 1002 Square Distance[DP 打印方案]


    Square Distance

     
     Accepts: 73
     
     Submissions: 598
     Time Limit: 4000/2000 MS (Java/Others)
     
     Memory Limit: 65536/65536 K (Java/Others)
    问题描述
    一个字符串被称为square当且仅当它可以由两个相同的串连接而成. 例如, "abab", "aa"是square, 而"aaa", "abba"不是.
    
    两个长度相同字符串之间的hamming distance是对应位置上字符不同的位数.
    
    Alex有个偶数长度的字符串ss1s2...sns=s1​​s2​​...sn​​. 他想要找到一个字典序最小的square tt1t2...tnt=t1​​t2​​...tn​​ 使得ss和tt之间的hamming distance恰好是mm. 另外, ss和tt仅包含小写英文字母.
    输入描述
    输入包含多组数据, 第一行包含一个整数TT 1T500(1T500)表示测试数据组数. 对于每组数据:
    
    第一行包含两个整数nn和mm 1n10000mnn(1n1000,0mn,n is even)表示字符串的长度和hamming distance. 第二行包含一个字符串ss.
    输出描述
    对于每组数据, 如果不存在这样的一个square, 输出"Impossible" (不包含引号). 否则, 输出字典序最小的square.
    
    输入样例
    3
    4 1
    abcd
    4 2
    abcd
    4 2
    abab
    输出样例
    Impossible
    abab
    aaaa


    因为要字典序最小打印,所以倒着保存状态
    f[i][j]表示i到n/2且hamming distance为j是否可行
    DP一遍之后贪心从头开始选择就行了
    //
    //  main.cpp
    //  bc87-1002
    //
    //  Created by Candy on 10/1/16.
    //  Copyright © 2016 Candy. All rights reserved.
    //
    
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <string>
    using namespace std;
    const int N=1005,V=1e6+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x;
    }
    int T,n,m,l,d[N][N];//dao xu
    char s[N],t[N];
    void dp(){
        memset(d,0,sizeof(d));
        d[l+1][0]=1;
        for(int i=l;i>=1;i--)
            for(int j=0;j<=m;j++){
                if(s[i]==s[i+l]) {
                    d[i][j]|=d[i+1][j];
                    if(j>=2) d[i][j]|=d[i+1][j-2];
                }else{
                    if(j>=1) d[i][j]|=d[i+1][j-1];
                    if(j>=2) d[i][j]|=d[i+1][j-2];
                }
                //printf("d %d %d %d
    ",i,j,d[i][j]);
            }
        if(!d[1][m]){printf("Impossible
    ");return;}
        int res=m;
        for(int i=1;i<=l;i++)
            for(int k=0;k<26;k++){
                int tmp=(s[i]-'a'!=k)+(s[i+l]-'a'!=k);
                if(d[i+1][res-tmp]){
                    t[i]=t[i+l]=k+'a';
                    res-=tmp;
                    break;
                }
            }
        for(int i=1;i<=n;i++) putchar(t[i]);
        putchar('
    ');
    }
    int main(int argc, const char * argv[]) {
        T=read();
        while(T--){
            n=read();m=read(); l=n/2;
            scanf("%s",s+1);
            dp();
        }
        return 0;
    }
  • 相关阅读:
    mybatis使用*号查询数据丢失问题
    设计四个线程,其中两个线程每次对j增加1,另外两个线程对j每次减1,写出程序
    用代码实现以下程序:篮子中有10个玩具,每60秒取出3个,同时每40秒向篮子中放入1个,不断重复上述动作,当篮子中剩余玩具不足3个是,程序结束
    伽马分布的性质
    三角函数公式
    微分和积分的中值定理
    一些需要理解掌握的知识点
    一阶微分不变性
    泰勒展开和麦克劳林级数
    重要极限(1+1/n)的n次方
  • 原文地址:https://www.cnblogs.com/candy99/p/5925801.html
Copyright © 2020-2023  润新知