BNU 29022 Myth Busters (dfs)

题意:给定N个长度为4的字符串,字符串中只有数字,现在可以将某个字符串全排列,通过在数字之间进行加减乘除和括号5种操作,得到的值是否等于10。求出这N个字符串是否都满足条件。


对于每个字符串,求出它的全排列,对于它的每一个排列,枚举两两之间的加减乘除操作,括号的优先级就用dfs枚举,这样能求出所有的情况。

发现错在一个很神奇的地方,当除法操作,除数为0时,返回-INF(INF为INT_MAX),和返回随意一个值,得到的答案不同,返回-INF时就wa了..................


#include <iostream>
#include <algorithm>
#include <cmath>
#include<functional>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <climits>//形如INT_MAX一类的
#define MAX 1111
#define INF 0x7FFFFFFF
using namespace std;

int n;
char s[11];
int a[11],b[11],op[11],pos[11];
int tag;

int cal(int x,int y,int kind) {
    if(kind == 0) return x + y;
    if(kind == 1) return x - y;
    if(kind == 2) return x * y;
    if(kind == 3) {
        if(y == 0) return 0;
        return x / y;
    }
}

void dfs(int ope[],int num[],int step) {

    if(tag == 1) return ;
    if(step == 0) {
        //cout << num[0] << endl;
        if(num[0] == 10) tag = 1;
        return ;
    }
//    if(step == 1) {
//        cout << num[0] << ' ' << num[1] << endl;
//    }
    int tmp1[11],tmp2[11];
    for(int i=0; i<step; i++) {
        for(int j=0; j<i; j++) tmp1[j] = num[j];
        tmp1[i] = cal(num[i],num[i+1],ope[i]);
        for(int j=i+1; j<step; j++) tmp1[j] = num[j+1];

        for(int j=0; j<i; j++) tmp2[j] = ope[j];
        for(int j=i; j<step-1; j++) tmp2[j] = ope[j+1];
        dfs(tmp2,tmp1,step - 1);
    }
}

bool solve() {
    tag = 0;
    for(int i=0; i<4; i++) b[i] = a[i];

    for(int i=0; i<4; i++) {
        for(int j=0; j<4; j++) {
            for(int k=0; k<4; k++) {
                op[0] = i;
                op[1] = j;
                op[2] = k;
                dfs(op,b,3);
                if(tag) return 1;
            }
        }
    }
    return 0;
}

int main() {
    while(scanf("%d",&n) && n) {
        int flag = 1;
        for(int i=0; i<n; i++) {
            scanf("%s",s);
            int ok = 0;
            if(flag == 0) continue;
            for(int j=0; j<4; j++) a[j] = s[j] - '0';
            sort(a,a+4);
            do {
                if(solve()) {
                    ok = 1;
                    break;
                }
            } while(next_permutation(a,a+4));
            if(!ok) {
                flag = 0;
            }
        }
        if(flag) puts("TRUE");
        else puts("BUSTED");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值