返回顶部
大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。人生如梦,一尊还酹江月。

Cyborg Genes UVA - 10723

题意翻译

【题目描述】

输入两个AAA~ZZZ组成的字符串(长度均不超过303030),找一个最短的串,使得输入的两个串均是它的子序列(不一定连续出现)。你的程序还应统计长度最短的串的个数。

e.g.:ABAAXGFe.g.:ABAAXGFe.g.:ABAAXGF和AABXFGAAABXFGAAABXFGA的最优解之一为AABAAXGFGAAABAAXGFGAAABAAXGFGA,一共有999个解。

【输入格式】

有多组数据。第一行一个整数TTT表示数据组数。接下来的2T2T2T行,每行一个字符串,含义如题所示。

【输出格式】

TTT行。第iii行格式为

Case #i: x y

其中xxx为最短串的长度,yyy为最优解的个数。

题目描述

PDF

输入输出格式

输入格式:

输出格式:

输入输出样例

输入样例#1: 复制
3
ABAAXGF
AABXFGA
ABA
BXA
AABBA
BBABAA
输出样例#1: 复制
Case #1: 10 9
Case #2: 4 1
Case #3: 8 10


f[i][j]表示第一个处理到i,第二个处理到j的最短长度,g表示个数

注意输入用getline,据说数据很坑

第一次用scanf("%s")没过
#include<bits/stdc++.h>
using namespace std;

const int maxn = 110;

int f[maxn][maxn],g[maxn][maxn],kase=0;

int main() {
    int t;
    scanf("%d\n",&t);
    while(t--) {
        memset(f,0,sizeof(f));
        memset(g,0,sizeof(g));
        string a,b;
        getline(cin,a);
        getline(cin,b);
        int lena=a.size(),lenb=b.size();
        for(int i=0;i<=lena;i++) f[i][0]=i,g[i][0]=1;
        for(int i=0;i<=lenb;i++) f[0][i]=i,g[0][i]=1;
        for(int i=1;i<=lena;i++)
            for(int j=1;j<=lenb;j++) {
                if(a[i-1]==b[j-1]) f[i][j]=f[i-1][j-1]+1;
                else f[i][j]=min(f[i-1][j],f[i][j-1])+1;
            }
        for(int i=1;i<=lena;i++)
            for(int j=1;j<=lenb;j++) {
                if(a[i-1]==b[j-1]) g[i][j]=g[i-1][j-1];
                else if(f[i-1][j]>f[i][j-1]) g[i][j]=g[i][j-1];
                else if(f[i-1][j]<f[i][j-1]) g[i][j]=g[i-1][j];
                else g[i][j]=g[i-1][j]+g[i][j-1];
            }
        printf("Case #%d: %d %d\n",++kase,f[lena][lenb],g[lena][lenb]);
    }
    return 0;
}
View Code

 

posted @ 2019-05-18 16:18  plysc  阅读(187)  评论(0编辑  收藏  举报