Light OJ 1110 - An Easy LCS (LCS+字典序最小路径记录)

来源:互联网 发布:海信32寸网络电视价格 编辑:程序博客网 时间:2024/03/29 08:06

传送门:http://lightoj.com/volume_showproblem.php?problem=1110
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26825

题目大意:求出两个字符串字典序最小的最长公共子序列。

解题思路:过程与求O(n*m)求LCS一样,转移时候加入更新转移当前字典序最小的LCS即可。

Code:

/*   W          w           w        mm          mm             222222222       7777777777777    *//*    W        w w         w        m  m        m  m          222        22              7777    *//*    w        w w         w        m  m        m  m                     22              777     *//*     w      w   w       w        m    m      m    m                    22              77      *//*     w      w    w      w        m    m      m    m                 222                77      *//*      w    w      w    w        m      m    m      m              222                  77      *//*      w    w      w    w        m      m    m      m            222                    77      *//*       w  w        w  w        m        m  m        m         222                      77      *//*       w  w        w  w        m        m  m        m      222                         77      *//*        ww          ww        m          mm          m     222222222222222             77      *///#pragma comment(linker, "/STACK:102400000,102400000")//C++//int size = 256 << 20; // 256MB//char *p = (char*)malloc(size) + size;//__asm__("movl %0, %%esp\n" :: "r"(p));//G++#include<set>#include<map>#include<queue>#include<stack>#include<ctime>#include<deque>#include<cmath>#include<vector>#include<string>#include<cctype>#include<cstdio>#include<cstdlib>#include<cstring>#include<sstream>#include<iostream>#include<algorithm>#define REP(i,s,t) for(int i=(s);i<=(t);i++)#define REP2(i,t,s) for(int i=(t);i>=(s);i--)using namespace std;typedef long long ll;typedef unsigned long long ull;typedef unsigned long ul;int T;const int N=110;char a[N],b[N];int dp[N][N];char s[N][N][N];int x,y;void debug(int x,int y){    printf("\n ");    REP(i,0,y-1)    {        printf(" %c",b[i]);    }    printf("\n");    REP(i,1,x)    {        printf("%c",a[i-1]);        REP(j,1,y)        {            printf(" %d",dp[i][j]);        }        printf("\n");    }    printf("\n");}void solve(){    x=strlen(a);    y=strlen(b);    memset(s,0,sizeof(s));    memset(dp,0,sizeof(dp));    REP(i,0,x-1)    {        REP(j,0,y-1)        {            if(a[i]==b[j])            {                dp[i+1][j+1]=dp[i][j]+1;                REP(k,0,dp[i][j]-1)                {                    s[i+1][j+1][k]=s[i][j][k];                }                s[i+1][j+1][dp[i][j]]=a[i];            }            else            {                if(dp[i+1][j]>dp[i][j+1])                {                    dp[i+1][j+1]=dp[i+1][j];                    strcpy(s[i+1][j+1],s[i+1][j]);                }                else if(dp[i+1][j]<dp[i][j+1])                {                    dp[i+1][j+1]=dp[i][j+1];                    strcpy(s[i+1][j+1],s[i][j+1]);                }                else                {                    dp[i+1][j+1]=dp[i][j+1];                    if(strcmp(s[i+1][j],s[i][j+1])<0)                    {                        strcpy(s[i+1][j+1],s[i+1][j]);                    }                    else                    {                        strcpy(s[i+1][j+1],s[i][j+1]);                    }                }            }        }    }}int main(){  #ifdef ONLINE_JUDGE  #else    freopen("test.in","r",stdin);  #endif  int ca=1;  scanf("%d",&T);  while(T--)  {    scanf("%s%s",a,b);    solve();    printf("Case %d: ",ca++);    if(dp[x][y]==0)    {        printf(":(\n");        continue;    }    else    {        printf("%s\n",s[x][y]);    }    //debug(x,y);  }  return 0;}
0 0