ZOJ Problem Set - 1003 Crashing Balloon(DFS)

题目链接
Input
Pairs of unequal, positive numbers, with each pair on a single line, that are claimed scores from a game of crashing balloon.
Output
Numbers, one to a line, that are the winning scores, assuming that the player with the lower score always challenges the outcome.
Sample Input
343 49
3599 610
62 36

Sample Output
49
610
62

题目大意是给两个一大一小的数,判断它们之间是否有唯一的相同公因数。因为100以内的数分解可能有多种结果,例如100可以分解为2,50/25,4/,因为气球只能扎破一次,所以两种分解结果是不一样的。所以在小数分解产生多种分解结果时要分别对大数进行一次dfs,判断所有情况。
小数挑战成功的唯一情况是小数能够分解成功而大数无法分解,其他情况则挑战失败。

一开始只考虑到一种分解结果的代码,导致wrong answer:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int flag1, flag2;
int n1, n2, tmp, vis[10010];

int DFS2(int t, int cur)
{
    if(t == n2){
        flag2 = 1;
        return 1;
    }
    else if(t > n2){
        return 0;
    }
    for(int i = cur;i <= 100;i++){
        vis[i] = 1;
        t *= i;
        if(!DFS2(t,i+1)){
            vis[i] = 0;
            t /= i;
        }
        else{
            cout << "n2 i: " << n2 << " " << i << endl;
            return 1;
        }
    }
    return 0;
}

void DFS1(int t, int cur)
{
    if(t == n1){
        flag1 = 1;
    }
    else if(t > n1){
        return;
    }
    for(int i = cur;i <= 100;i++){
        if(!vis[i]){
            t *= i;
            DFS1(t,i+1);
            t /= i;
        }
    }
}

int main()
{
    //freopen("D://in.txt","r",stdin);
    while(cin >> n1 >> n2){
        memset(vis,0,sizeof(vis));
        if(n1 < n2){
            swap(n1,n2);
        }
        if(n1 <= 100 && n2 <= 100){
            if(n1 == n2){
                cout << n2 << endl;
            }
            else{
                cout << n1 << endl;
            }
            continue;
        }
        flag1 = flag2 = 0;
        DFS2(1,2);
        DFS1(1,2);
        if(flag2 && !flag1){
            cout << n2 << endl;
        }
        else{
            cout << n1 << endl;
        }
    }
    return 0;
}

把对DFS1的调用放到DFS2的函数体中,再对DFS1的函数体做一些调整,考虑到所有分解结果后AC 了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int flag1, flag2;
int n1, n2, tmp, vis[10010];

int DFS1(int t, int cur)
{
    if(t == n1){
        return 1;
    }
    else if(t > n1){
        return 0;
    }
    for(int i = cur;i <= 100;i++){
        if(!vis[i]){
            t *= i;
            vis[i] = 1;
            if(DFS1(t,i+1))
                return 1;
            t /= i;
            vis[i] = 0;
        }
    }
    return 0;
}

int DFS2(int t, int cur)
{
    if(t == n2){
        flag2 = 1;
        if(DFS1(1,2)){
            flag1 = 1;
            return 1;
        }
    }
    else if(t > n2){
        return 0;
    }
    for(int i = cur;i <= 100;i++){
        vis[i] = 1;
        t *= i;
        if(!DFS2(t,i+1)){
            vis[i] = 0;
            t /= i;
        }
        else{
            return 1;
        }
    }
    return 0;
}

int main()
{
    while(cin >> n1 >> n2){
        memset(vis,0,sizeof(vis));
        if(n1 < n2){
            swap(n1,n2);
        }
        flag1 = flag2 = 0;
        DFS2(1,2);
        if(flag2 && !flag1){
            cout << n2 << endl;
        }
        else{
            cout << n1 << endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值