poj2264 최단 경로 + 기록 경로 + 문자 조합 + 귀속

3410 단어
좋은 문제
처음에는 자신의 사고방식에 따라 썼는데, 왜냐하면 경로를 기록할 줄 모르기 때문이다
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

char str1[105],str2[105];
int t[110][110];
char a[110];

int main()
{
    while(scanf("%s%s",str1,str2)!=EOF)
    {
        int len1=strlen(str1);
        int len2=strlen(str2);
        for(int i=0;i<len1;i++)
            for(int j=0;j<len2;j++)
            t[i][j]=0;

        for(int i=0;i<len1;i++)
            for(int j=0;j<len2;j++)
                if(str1[i]==str2[j])
                    t[i+1][j+1]=t[i][j]+1;
                else
                    t[i+1][j+1]=max(t[i][j+1],t[i+1][j]);

        int pos=t[len1][len2]-1;
        int p=len1,k=len2;
        int tag1=1,tag2=1;
        while(t[p][k]){
            if(t[p][k]==t[p][k-1]){
                k--;
                tag2=0;
            }
            else if(t[p][k]==t[p-1][k]){
                p--;
                tag1=0;
            }
            else{
                if(tag1){
                    a[pos--]=str2[k-1];
                    p--;
                }
                else{
                    a[pos--]=str1[p-1];
                    k--;
                }
                tag1=1;
                tag2=1;
            }
        }

        int p1=0,p2=0;
        for(int i=0;i<len1;i++)
            if(a[0]==str1[i]){
                p1=i;
                break;
            }
            else
                printf("%c",str1[i]);

        for(int j=0;j<len2;j++)
            if(a[0]==str2[j]){
                p2=j;
                break;
            }
            else
                printf("%c",str2[j]);

        int i,j;
        pos=0;
        for(i=p1,j=p2;i<len1||j<len2;)
            if(str1[i]==a[pos]&&a[pos]==str2[j]&&i<len1&&j<len2){
                printf("%c",str1[i]);
                i++;
                j++;
                pos++;
            }
            else{
                if(i<len1&&str1[i]!=a[pos])
                    printf("%c",str1[i++]);
                else if(j<len2&&a[pos]!=str2[j])
                    printf("%c",str2[j++]);
            }

        puts("");
    }

    return 0;
}

나중에 인터넷에서 다른 사람의 코드를 배워서 귀속+거슬러 올라가기+경로를 기록하는 코드를 이해했다
#include<stdio.h>
#include<string.h>

char str1[105],str2[105];
int path[110][110];

void print(int n,int m){
    if(!n&&!m)
        return ;

    if(path[n][m]==m+1){
        print(n-1,m-1);
        putchar(str1[n]);
    }
    else if(path[n][m]==m){
        print(n-1,m);
        putchar(str1[n]);
    }
    else{
        print(n,m-1);
        putchar(str2[m]);
    }
    return ;

}

int main()
{
    while(scanf("%s%s",str1+1,str2+1)!=EOF)
    {
        int len1=strlen(str1+1);
        int len2=strlen(str2+1);
        int t[110][110]={0};

        for(int i=1;i<=len1;i++)
            for(int j=1;j<=len2;j++)
                if(str1[i]==str2[j])
                    t[i][j]=t[i-1][j-1]+1,path[i][j]=j+1;
                else if(t[i][j-1]>t[i-1][j])
                    t[i][j]=t[i][j-1],path[i][j]=j-1;
                else
                    t[i][j]=t[i-1][j],path[i][j]=j;

        print(len1,len2);

        puts("");
    }

    return 0;
}

좋은 웹페이지 즐겨찾기