Timus 1501

搞了一天终于AC了,感觉题目有点问题,没有说有多个可行顺序的情况如何输出,然而测试数据是按照某一个顺序输出的。

比如说:101  010   是按照111222输出,其实(如果题意我没有读错的话)121212   221112应该也是正确的。听说这道题有一定的改动,是不是出题人忽视了呢????

令res[i][j]表示串1的前i个字符与串2的前j个字符是否能够按照规则分成两堆。

res[i][j]= (res[i-1][j-1] && str1[i]!=str2[j]) || (res[i-2][j] && str1[i]!=str1[i-1]) || (res[i][j-2] && str2[j]!=str2[j-1]);

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
char str1[1010],str2[1010];
short res[1010][1010];
int work(int n)
{
    int i,j;
    res[0][0]=1;
    for(i=2;i<=n;i+=2)
        if(res[0][i-2] && str2[i-1]!=str2[i]) res[0][i]=1;
    for(i=2;i<=n;i+=2)
        if(res[i-2][0] && str1[i-1]!=str1[i]) res[i][0]=1;
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
        {
            if((i+j)%2==1) continue;
            if(str1[i]!=str2[j] && res[i-1][j-1]) res[i][j]=1;
            if(str1[i]!=str1[i-1] && res[i-2][j]) res[i][j]=1;
            if(str2[j]!=str2[j-1] && res[i][j-2]) res[i][j]=1;
        }
    return res[n][n];
}
int print(int n)
{
    int i,j;
    stack <int> S;
    i=j=n;
    while(i>0 || j>0)
    {
        if(res[i][j-2])
        {
            S.push(2); S.push(2);j-=2;
        }
        else if(res[i-1][j-1])
        {
            S.push(2); S.push(1); i--;j--;
        }
        else if(res[i-2][j])
        {
            S.push(1); S.push(1);i-=2;
        }
    }
    while(!S.empty())
    {
        printf("%d",S.top()); S.pop();
    }
    printf("\n");
    return 0;
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(res,0,sizeof(res));
        scanf("%s %s",str1+1,str2+1);
        str1[0]=str1[1]; 
        str2[0]=str2[1];
        if(work(n))
        {
            print(n);
        }
        else
        {
            printf("Impossible\n");
        }
    }
    return 0;
}
posted @ 2012-04-26 17:32  书山有路,学海无涯  阅读(251)  评论(0编辑  收藏  举报