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;
}

猜你喜欢

转载自blog.csdn.net/qq_43189757/article/details/89322809