URAL1780----格雷码的应用,数论

来源:互联网 发布:sql注入漏洞的原理 编辑:程序博客网 时间:2024/06/05 17:18

题目地址:http://acm.timus.ru/problem.aspx?space=1&num=1780

题目意思:

给你一个格雷码的二进制和格雷码本身

但是有部分被?代替,问你这个结果是否唯一

唯一就输出,不唯一就输出Ambiguity,不存在就输出Impossible

解题思路:

这题没有任何难度,唯一的问题就是要懂格雷码

下面给出格雷码的转换方式:

二进制码->格雷码(编码):从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应格雷码该位的值,最左边一位不变(相当于左边是0);
格雷码-〉二进制码(解码):从左边第二位起,将每位与左边一位解码后的值异或,作为该位解码后的值(最左边一位依然不变)。

另外就是,格雷码的左边第一位和二进制的左边第一位一定是相同的

了解了上面,就可以做了

那就不停的译码,编码,直到不能再编码或者译码了就出来

然后进行判断

下面上代码:

#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;const int maxn = 100000+10;int a[maxn];int b[maxn];char s1[maxn];char s2[maxn];int n;int main(){    while(~scanf("%s%s",s1,s2))    {        n = strlen(s1);        for(int i=0;i<n;i++)        {            if(s1[i]=='?')                a[i]=-1;            else                a[i]=s1[i]-'0';            if(s2[i]=='?')                b[i]=-1;            else                b[i]=s2[i]-'0';        }        bool f=true;        bool f2=true;        while(f&&f2)//当没推出新的或者有矛盾的时候退出        {            f=false;            //先由最右边往最左查            for(int i=n-1;i>=1;i--)            {                if(a[i]!=-1 && a[i-1]!=-1)                {                    int tmp = a[i]^a[i-1];                    if(b[i]==-1)                    {                        b[i]=tmp;                        f=true;                        //printf("b %d\n",i);                    }                    else                    {                        if(b[i]!=tmp)//这里已经不符合规则了,可以直接跳转了                        {                            f2=false;                            break;                        }                    }                }                if(a[i]!=-1 && b[i]!=-1)                {                    int tmp = a[i]^b[i];                    if(a[i-1] == -1)                    {                        a[i-1]=tmp;                        //printf("a %d\n",i-1);                        f=true;                    }                    else                    {                        if(a[i-1] != tmp)                        {                            f2=false;                            break;                        }                    }                }                if(b[i]!=-1 && a[i-1]!=-1)                {                    int tmp = b[i]^a[i-1];                    if(a[i]==-1)                    {                        f=true;                        a[i]=tmp;                    }                    else                    {                        if(a[i]!=tmp)                        {                            f2=false;                            break;                        }                    }                }            }            //从最左边忘右查            if(f2)            for(int i=1;i<n;i++)            {                if(b[i]!=-1 && a[i-1]!=-1)                {                    int tmp = b[i]^a[i-1];                    if(a[i]==-1)                    {                        f=true;                        a[i]=tmp;                    }                    else                    {                        if(a[i]!=tmp)                        {                            f2=false;                            break;                        }                    }                }                if(a[i]!=-1 && a[i-1]!=-1)                {                    int tmp = a[i]^a[i-1];                    if(b[i]==-1)                    {                        b[i]=tmp;                        f=true;                        //printf("b %d\n",i);                    }                    else                    {                        if(b[i]!=tmp)//这里已经不符合规则了,可以直接跳转了                        {                            f2=false;                            break;                        }                    }                }                if(a[i]!=-1 && b[i]!=-1)                {                    int tmp = a[i]^b[i];                    if(a[i-1] == -1)                    {                        a[i-1]=tmp;                        //printf("a %d\n",i-1);                        f=true;                    }                    else                    {                        if(a[i-1] != tmp)                        {                            f2=false;                            break;                        }                    }                }            }            if(!f2)                break;            //因为在译码和解码的时候没考虑到最左边的,所以拿出来特判            if(a[0] != -1 && b[0]==-1)            {                b[0]=a[0];                f=true;            }            if(a[0] == -1 && b[0]!=-1)            {                a[0]=b[0];                f=true;            }        }        if(!f2 || a[0]!=b[0])//当有矛盾的时候,最左边的是特判的        {            printf("Impossible\n");        }        else        {            bool f3=true;            for(int i=0;i<n;i++)            {                if(a[i]==-1 || b[i] == -1)//仍然还有没推出来,那就不唯一                {                    printf("Ambiguity\n");                    f3=false;                    break;                }            }            if(f3)            {                for(int i=0;i<n;i++)                    printf("%d",a[i]);                printf("\n");                for(int i=0;i<n;i++)                    printf("%d",b[i]);                printf("\n");            }        }    }    return 0;}