XDOJ.T172_构造表达式(XDOJ五星级题目之一)

这篇博客介绍了XDOJ中一道五星级难题,涉及构造序列1到n的表达式,使结果为0。问题的关键在于在数字间插入' + ', '- ', 和空格运算符。当n=3时,只有一个表达式1+2-3=0,输出结果为1。博主分享了老师的解题思路,包括使用递归排列组合运算符并判断结果,以及处理' '运算符的特殊性。博主还提到了代码实现的语言转换问题,并暗示可能存在更简洁的算法。" 119895613,7427859,系统架构设计与嵌入式技术详解,"['系统架构', '嵌入式开发', '软件设计', '编译优化', '实时系统']
摘要由CSDN通过智能技术生成

这题是我在XDOJ中长时间以来没有做出来的三道题目之一。有一次无意中发现这道题是五星级难题,连老师都说这题是他认为XDOJ中较难的题之一。好吧,不扯理由了,说白了,还是我太菜了,最后直到老师把他的题解发出来我才把这题做出来。
这题最棘手的是在数字之间加入’ '运算符,额,我先贴题目吧。

标题

构造表达式

类别

综合

时间限制

1S

内存限制

100Kb

问题描述

给定一个表示序列长度的整数n(3<=n<=9)。在序列1 2 3…n中插入‘+’,‘-’,
‘ ’构造表达式,插入‘ ’表示前后两个数字构成一个整数,例如1 2 -3 -4 -5=0。
输出构造的所有表达式中,结果为0的表达式的数量,例如n=3时,只有表达式1+2-3=0,
输出结果为1。

这题最棘手的是在数字之间加入’ ‘运算符
如果数字之间只可能有’+‘和’-’,那么只需要对运算符用递归进行排列组合,然后判断结果是否为0
很显然,’ ‘运算符需要优先考虑,然后同样只需要考虑’+‘和’-‘像上一行所说的一样
算法中定义一个op[9]字符数组专门储存运算符,因为n<=9,所以数字之间的运算符最多有8个,再加上’\0’,数组长度总共为9

输入说明

输入数据为一个整数n(n<10),表示序列长度,同时表示输入序列为“1 2 3…n”。

这个序列非常特殊,op数组中下标为index的运算符(即op[index])的两侧的数的值分别为index+1与index+2
例如:op[0]是第一个运算符,那么这个运算符两侧的数的值分别为1与2

输出说明

对于每一组数据,输出一个整数,表示构造的表达式中结果为0的表达式数量。

输入样例

3

输出样例

1
下面是老师的代码:(如果你跟我同班,那就不用看了。什么?你是我老师?千万别让我挂科,你看我都这么努力了来这里发题解)

#include <cstdio>
#include <cstring>

int n;
char op[9];
int idx;    // compute函数求解过程中扫描的操作符数组当前索引,初值为0,每次compute函数调用时会清零,用于compute和get_num、get_op共享 
int count;	// 解的数量,在compute函数中每遇见一个符合条件的解,这里增加1 

// 从当前操作符idx索引开始向后扫描,合并所有的数字(即' '操作符连接的数字) 
// 返回合并后的数字 

int get_num()
{
   
	// 注意idx+1和idx+2的值,在这里idx代表操作符数组索引,因为本题中数列为1开始递增的自然数,因此我们不用单独保存数列的值,而是通过idx间接计算得到操作符左、右的数列数字,它们分别是idx+1,idx+2
	// Why? 操作符索引idx以0为第一个元素,因为第一个操作符应出现在数列1、2数字之间,因此建立映射关系为idx+1,idx+2 
	// get_num函数会持续扫描直到遇到的操作符不是' ',这样可以连续合并多个数字,它会遇到第一个不是' '操作符时退出,见compute 
	int d = idx+1;
	while(op[idx] == ' ' && idx < n-1)
	{
   
		d = d*10 + (idx+2);
		idx++;
	}
	return d;
}

// 从当前位置获取(+/-)操作符,get_op函数当前位置可能有两种情况:1、已到操作符数组末尾 (想象一下只有' '操作符的情况);2、当前位置必为'+'/'-',因为get_op之前会调用get_num,见上面描述 
// get_op返回的是+1或者-1或者0,0代表结束,+1代表+运算符,-1代表-运算符 ,为何这么取值?见compute 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值