poj 1950 Dessert 深度优先搜索

本文介绍了一种使用深度优先搜索解决特定数学问题的方法。通过递归地构建表达式树并评估可能的结果,来寻找所有可能使得给定数学等式成立的表达式组合。特别注意了在处理数字连接形成更大数字的情况下的复杂逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://poj.org/problem?id=1950

赤裸裸的深度优先搜索,只是在考虑“.”时的处理要麻烦一些,要小心处理啊,不然错的很严重。

//dfs
#include <stdio.h>
#include <string.h>
int n;

char str[21][16];
char strtmp[16];
int num, numtmp;

int res;

void dfs(int cur, int next)
{
    if(cur > n)return;
    if(cur == n&&res == 0){
        if(num < 20){
            strcpy(str[num], strtmp);
            num ++;
        }
        else num ++;
        return;
    }
//+
    res += next;
    strtmp[numtmp] = '+';
    numtmp ++;
    dfs(cur+1, next+1);
    numtmp --;
    res -= next;

//-
    res -= next;
    strtmp[numtmp] = '-';
    numtmp ++;
    dfs(cur+1, next+1);
    numtmp --;
    res += next;

//.
    if(numtmp>0){
        int tmp;
		int j, k = 1;
		int tp = cur, tm;
        if(next >= 10)tmp = 100*cur + next;
        else tmp = 10*cur + next;
        if(strtmp[numtmp-1] == '+')res = res - cur + tmp;
        else if(strtmp[numtmp-1] == '-')res = res + cur - tmp;
        else {
			for(j = numtmp-1; j >=0; j --){
				if(strtmp[j] != '.'){
					break;
				}
				tp --;
			}
//			printf("tp = %d\n", tp);
			tm = tp;
			tp ++;
			for(k = j+1; k < numtmp; k ++){
				if(tp >= 10){
					tm = 100*tm + tp;
				}
				else tm = 10*tm + tp;
				tp ++;
			}
			if(next >= 10)tmp = 100*tm + next;
			else tmp = 10*tm + next;

			if(j == -1) res = tmp;
			else if(strtmp[j] == '+')res = res - tm + tmp;
			else if(strtmp[j] == '-')res = res + tm - tmp;
		}
        strtmp[numtmp] = '.';
        numtmp ++;
        dfs(cur+1, next+1);
        numtmp --;
        if(strtmp[numtmp-1] == '-')res = res + tmp - cur;
        else if(strtmp[numtmp-1] == '+')res = res - tmp + cur;
		else {
			if(j == -1)res = tm;
			else if(strtmp[j] == '-')res = res + tmp - tm;
			else if(strtmp[j] == '+')res = res - tmp + tm;
		}
    }
    else {
        int tmp;
        tmp = 10*1 + next;
        res = tmp;
        strtmp[numtmp] = '.';
        numtmp ++;
        dfs(cur+1, next+1);
//        numtmp --;
    }
}

int main()
{
    int i, j;
    while(scanf("%d", &n)!=EOF){
        num = 0;
        numtmp = 0;
        res = 1;
        dfs(1, 2);
        if(num >= 20){
            for(j = 0; j < 20; j ++){
                for(i = 0; i < n - 1; i ++){
                    printf("%d %c ", i+1, str[j][i]);
                }
                printf("%d\n", i+1);
            }
        }
        else {
            for(j = 0; j < num; j ++){
                for(i = 0; i < n - 1; i ++){
                    printf("%d %c ", i+1, str[j][i]);
                }
                printf("%d\n", i+1);
            }
        }
        printf("%d\n", num);
    }
    return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值