zoj 1003

这个题目是搜索的经典题目,深搜来找到解进而进行两个姐相容性的判定。
#include<stdio.h>
#include<iostream>
using namespace std;

bool flag;

bool check(int big,int small,int n)
{
    int i;
    for(i=n;i>1;i--)
    {
        if(small%i==0){
            if(check(big,small/i,i-1))return true;
        }
        if(big%i==0){
            if(check(big/i,small,i-1))return true;
        }
    }

    if(small == 1){       //分数少者有可能没有说谎
        flag = true;
    }
    else if(!flag){       //如果分少的说谎了(包含了分数多者说谎的情况)
        return true;
    }

    if(big==1&&small==1){ //两个人的分数相容
        return true;
    }

    return false;        //得分少者的分数能被分解结束了,但是得分大不能被分解,返回上一层继续搜索相容的情况
}

int main()
{
    int a,b;
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        int big,small;

        flag = false;

        big = a>b?a:b;
        small = a>b?b:a;

        int win=big;
        if(!check(big,small,100))
        {
            win=small;
        }
        printf("%d\n",win);
    }
    return 0;
}

(1)为什么这样做呢?由于情况有很多种,如果你要用数组记录所有的可能的情况,至少得开一个100*100的二维数组,还有可能就是给出的数字很大,进行因式分解是不好处理的,应为这个题目要求的数字绝对不能出现两个相同数字的乘积。如果求出两个所有可能的情况,进行比兑,但是这种思想实在不知道怎么样操作。一种办法就是用nlog(n)的方法进行解的搜索。如果找到一个这两个数的两种可能的分解方案,就进行判定,这两个方案是否相容,如果相容则可以得出结果;如果不相容,继续找相容的情况了。算法的时间复杂度是(nLog(n))。这个题目需要想清楚的地方就是,如果判断解是否相容。判断解相容有下列几种情况:

      1》如果小的数字到一,可以认为小的没有撒谎。此时要判定大的分数是否被整除到一。如果大的被整除到一,说明这种情况下,这两个分数是相容的,判定大的赢;如果没有被整除到一,显然大的在说谎,此时由于不知道小的是否在说谎,所以返回上一层,再进行判断,找有没有跟大的分数相容的情况,如果有,就判断大的赢,显然这种情况是不存在的,可以直接判断小的赢,这里存在一个剪枝,但是在程序中没有体现出来。

      2》如果小的数字没到一。显然说谎了,那么就判定分数大的赢了;

(2)这个方法还有说明改进的地方?

(3)还有没有其他的方法呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值