ZOJ 1003

//2358423     2010-11-25 22:43:52     Accepted     1003     C     0     160     VRS
//1003 踩气球
//历经千辛万苦终于a了,痛苦啊~~~~感觉这代码太暴力了
//
//就是找出两个数所有各不相同的因子,如24和12的所有因子为 2,3,4,6,8,12 , 再在这些因子中搜索,
//看是否能重新乘出给出的两个数。若两者都说真话就大者胜,若两者都说假话(都含大于100的质因子)就维持大者胜,
//若挑战者(小)真,大者说假话,则挑战者胜。
//
#include<stdio.h>
#include<string.h>

 

#define bool int

bool balloon[105];
int factor[105];
bool factorStatus[105];
long a,b;
bool aOK,bOK,aTrue;
int factorLen;

//深搜
//其实相当于回溯,首先利用因子组合成挑战者的报数,搜索过程标记用过的因子;然后利用剩下的因子组合成大数者的报数
//用mul分别记录a,b的值,每次除以因子直到等于1
void dfs(int k,long mul)
{
    int i;
    if(k==factorLen)
        return ;
    else
    {
        for(i=k;i<factorLen && factor[i]<=mul;i++)
        {
            if(bOK==1)
                return ;
            //已经标志过的因子跳过
            if(factorStatus[i]==1)
                continue;
            if(mul%factor[i]==0)
            {
                mul/=factor[i];
                factorStatus[i]=1;
                if(mul==1)
                {
                    if(aOK==0)
                    {
                        aOK=1;
                        dfs(0,b);
                        aOK=0;       //撤销找到a的标志,方便回溯
                        aTrue=1;     //表明生成过挑战者报数,用于输出的判断
                    }
                    else
                    {
                        bOK=1;
                        return ;
                    }
                }           
                dfs(i+1,mul);
                //重新回退深入前的状态,方便回溯
                mul*=factor[i];
                factorStatus[i]=0;
            }
        }
    }
}

int main()
{
    long temp;
    int i,j;
    bool resVal;
    while(scanf("%ld %ld",&a,&b)!=EOF)
    {
        //保持挑战者是a(较小者)
        if(a>b)
        {
            temp=b;
            b=a;
            a=temp;
        }
        memset(balloon,0,sizeof(balloon));
        memset(factor,0,sizeof(factor));
        memset(factorStatus,0,sizeof(factorStatus));
        //找出两者的因子
        for(i=2;i<=100 && i<=a;i++)
            if(a%i==0)
                balloon[i]=1;
        for(i=2;i<=100 && i<=b;i++)
            if(b%i==0)
                balloon[i]=1;
        j=0;
        for(i=2;i<=100;i++)
            if(balloon[i]==1)
                factor[j++]=i;

        aOK=aTrue=bOK=0;
        factorLen=j;
        resVal=0;
        //如果挑战者报数是1,特殊处理
        if(a==1)
        {
            aTrue=1;
            aOK=1;
            dfs(0,b);
        }
        else
            dfs(0,a);

        if(bOK==1)   //两者都是真话
            resVal=1;
        else if(aTrue==1 && bOK==0)  //ab含唯一的公因子,或a真b含大于100的质因子
            resVal=0;
        else      //两者都有大于100的质因子,或a含大于100的质因子b不含
            resVal=1;

        if(!resVal)
            printf("%ld\n",a);
        else
            printf("%ld\n",b);
    }
    return 0;
}

你可能感兴趣的:(ZOJ)