According to Bartjens UVA - 817

这篇博客探讨了一道编程题,题目要求处理特定输入字符串并尝试插入符号使计算结果等于2000。特判情况为输入'2000='时直接输出'IMPOSSIBLE'。博主详细阐述了解题思路,包括计算可插入符号的位置、暴力搜索策略以及递归求解过程中数组记录的状态。在递归过程中,博主强调了正确处理乘法、加减运算及前导零的重要性。最后,博主分享了实现代码,并在遍历所有可能后输出满足条件的解决方案。

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

思路比较简单,但是实现起来比较复杂的一道题目。首先读取输入的串,这里有一个特判,如果输入的是“2000=”,那么就直接输出无解(即“IMPOSSIBLE”)就可以了。然后对于输入的串,首先计算出来输入的串的长度length,由于输入的串中包含字符“=”,那么除去这个符号之前的位置是不能够插入符号之外,能够插入符号的位置一共有length-2个地方。那么现在开始进行暴搜,暴搜的时候使用一个数组记录每一个插入位置的状况,用0表示插入的是‘*’,1表示插入的位置是‘+’,2表示插入的位置是‘-’,3表示不插入任何的符号,那么每次递归求解之后,判断目前的所有的位置是否已经试探结束,也就是处理到了能够插入的位置的最后一位,如果已经处理到了最后一位,那么就开始计算式子的结果,计算的时候注意首先计算乘法运算,然后再计算加减运算,同时在计算的时候要注意排除前导零的情况,最后将计算结果返回。将得到的计算结果和2000进行比较,如果等于2000,那么就将字符串的式子还原出来并保存,最后在所有的情况全部测试结束之后就打印最终的结果即可,具体实现见如下代码:

#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;

int Problem;
string s;
set<string> st;
bool flag;
const int N = 30;
int length,record1[N],record2[N];
char sym[] = { '*', '+', '-' };

int cal(){
	int number[N], total_n = 0,total2=0;
	number[0] = s[0] - '0';
	for (int i = 0; i < length; i++){
		if (record1[i] == 3){//代表这个位置没有插入符号
			if (number[total_n] == 0) return 0;
			number[total_n] = number[total_n] * 10 + s[i + 1] - '0';
		}
		else{//代表这个位置是插入了符号
			total_n++;
			number[total_n] = s[i + 1] - '0';
			record2[total2++] = record1[i];
		}
	}
	int record3[N];
	int total3 = 0, num[N], total_m = 0;
	num[0] = number[0];
	for (int i = 0; i < total2; i++){
		if (record2[i] == 0){
			num[total_m] *= number[i + 1];
		}
		else{
			record3[total3++] = record2[i];
			total_m++;
			num[total_m] = number[i + 1];
		}
	}
	int ans = num[0];
	for (int i = 0; i < total3; i++){
		if (record3[i] == 1){
			ans += num[i + 1];
		}
		else
			ans -= num[i + 1];
	}
	return ans;
}

void dfs(int ind){
	if (ind == length){//最后的一个位置都已经处理结束,则开始特判
		int num = cal();
		if (num == 2000){
			flag = true;
			string temp = "";
			temp += s[0];
			for (int i = 0; i < length; i++){
				if (record1[i] == 3){
					temp += s[i+1];
				}
				else{
					temp += sym[record1[i]];
					temp += s[i + 1];
				}
			}
			st.insert(temp);
		}
		return;
	}
	for (int i = 0; i < 4; i++){
		record1[ind] = i;
		dfs(ind + 1);
	}
}

int main(){
	Problem = 0;
	while (cin >> s){
		Problem++;
		flag = false;
		if (s == "=") break;
		if (s == "2000="){
			cout << "Problem " << Problem << "\n";
			cout << "  IMPOSSIBLE\n";
			continue;
		}
		st.clear();
		length = s.size() - 2;//length代表的是可以插入符号的位置
		dfs(0);
		cout << "Problem " << Problem << "\n";
		if (flag){
			for (auto it : st){
				cout <<"  "<< it<<"=" << endl;
			}
		}
		else
			cout << "  IMPOSSIBLE\n";
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值