UVA - 817 According to Bartjens

Description

 According to Bartjens 

The wide dissemination of calculators and computers has itsdisadvantages. Even students in technical disciplinestend to exhibit a surprising lack of calculating ability. Accustomed tothe use of calculators and computers, many ofthem are unable to make calculations
like 7 * 8 mentally or like 13 *17 using pencil and paper. We all know, butwho cares?

Professor Bartjens cares. Professor Bartjens is a bit old fashioned.Hedecided to give his students some training incalculating without electronic equipment by creating a collection ofcalculation problems, (like 2100 - 100 = ...). Tosimplify grading the problems,
he constructed them so that almost allof them had 2000 as an answer. Not all ofthem, of course. His students would be smart enough to recognize thepattern, and fill in 2000 everywhere withoutfurther thinking.

Unfortunately Professor Bartjens’ printer driver turned out to be evenmore old-fashioned than the professor himself,and it could not interface with his new printer. Inspecting the printedproblems, he soon recognized the pattern: noneof the operations was
transmitted to the printer. A problem like:

2100-100=

was printed as:

2100100=

Fortunately, all the digits and the equal sign were still printed.

To make this bad situation much worse, Professor Bartjens’ source filehad disappeared. So Professor Bartjens hasanother problem: what were his original problems? Given the fact thatthe answer (most likely) should be 2000, theline 2100100= could have been
any one of the lines:

2100-100=
2*100*10+0=
2*100*10-0=
2*10*0100=
2*-100*-10+0=

Professor Bartjens does remember a few things about how he wrote theproblems:

  • He is sure that whenever he wrote down a number (other than 0),itwould not start with a zero. So2*10*0100= could not have been one of his problems.
  • He also knows he never wrote the number zero as anything but 0.So hewould not have a problem like2*1000+000=.
  • He used only binary operators, not the unary minus or plus, so2*-100*-10+0= was not an option either.
  • He used the operators +, - and * only, avoiding the operator /(afterall, they were first year students).
  • He knew all problems followed the usual precedence andassociativityrules.

You are to help Professor Bartjens recover his problem set bywriting aprogram that when given a row of digits,insert one or more of the operators +, - and * in such a way that thevalue of the resulting expression equals 2000.

Input

The input consists of one or more test cases. Each test case is asingle line containing n digits (‘0‘–‘9‘), 1 ≤n ≤9,followed by an equal sign. There will not be any blanks embedded in theinput, but there may be some after theequal sign.

The last test case is followed by a line containing only the equalsign. This line should not be processed.

Output

For each test case, print the word Problem, then the number of thecase, then all possible ways of insertingoperators in the row of digits such that the resulting expression hasthe value 2000, subject to Professor Bartjens’memory of how he wrote the problems.
Use the format shown below. Ifthere is more than one possible problem,write the problems in lexicographic order. Each possible problemshould be on a new line, indented 2 spaces. If there is no solution theanswer IMPOSSIBLE should be printed,indented 2 spaces.

Sample Input Output for the Sample Input
2100100=
77=
=
Problem 1
  2*100*10+0=
  2*100*10-0=
  2100-100=
Problem 2
  IMPOSSIBLE

题意:求在一个字符串中插入运算符使得结果是2000的所有的可能

思路:枚举每个位置得到如干个数字在回溯运算符得到结果,字典序输出

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <set>
using namespace std;
const int MAXN = 200;
const int INF = 0x3f3f3f3f;
typedef long long ll;

string str;
ll res[MAXN];
int N, M, op[MAXN];
set<string> f;

ll tran(int st, int ed) {
	if (str[st] == '0' && ed-st > 0)
		return -1;
	ll x = 0;
	for (int i = st; i <= ed; i++)
		x = x*10 + str[i]-'0';
	return x;
}

void cal() {
	int m = N-1;
	int len = str.length()+N-2;
	string p(len+1, '*');
	p[len--] = '=';
	for (int i = N-1; i >= 0; i--) {
		ll x = res[i];
		if (x == 0)
			p[len--] = '0';
		while (x) {
			p[len--] = x%10+'0';
			x /= 10;
		}
		if (i) {
			if (op[m-1] == 0) {
				p[len--] = '+';
				m--;
			}
			else if (op[m-1] == 1) {
				p[len--] = '-';
				m--;
			}
			else {
				p[len--] = '*';
				m--;
			}
		}
	}
	f.insert(p);
}

void findExpression(int cur, stack<ll> s) {
	if (cur == N-1) {
		ll ans = 0;
		while (!s.empty()) {
			ans += s.top();
			s.pop();
		}
		if (N > 1 && ans == 2000)
			cal();
		return;
	}
	for (int i = 0; i < 3; i++) {
		op[cur] = i;
		if (i == 0) {
			s.push(res[cur+1]);
			findExpression(cur+1, s);
			s.pop();
		}
		else if (i == 1) {
			s.push(-res[cur+1]);
			findExpression(cur+1, s);
			s.pop();
		}
		else {
			ll x = res[cur+1]*s.top();
			s.pop();
			s.push(x);
			findExpression(cur+1, s);
		}
	}
}

void solve(int cur, int n) {
	if (cur == str.length()-1) {
		N = n;
		stack<ll> s;
		s.push(res[0]);
		findExpression(0, s);
		return;
	}
	for (int i = cur; i < str.length()-1; i++) {
		ll x = tran(cur, i);
		if (x != -1) {
			res[n] = x;
			solve(i+1, n+1);
		}
	}
}

int main() {
	int cas = 1;
	while (cin>>str) {
		f.clear();
		if (str.length() == 1 && str[0] == '=')
			break;
		printf("Problem %d\n", cas++);
		solve(0, 0);
		if (f.size() == 0)
			printf("  IMPOSSIBLE\n");
		else {
			for (set<string>::iterator it = f.begin(); it != f.end(); it++)
				cout << "  " << *it << endl;
		}
	}
	return 0;
}

UVA - 817 According to Bartjens

时间: 2024-11-05 02:06:35

UVA - 817 According to Bartjens的相关文章

UVA - 817 According to Bartjens 暴力

题目大意:给出一个字符串,要求你在这个字符串里面加入符号,使得结果为2000 解题思路:直接暴力 #include<stdio.h> #include<string.h> #include<vector> #define maxn 30 using namespace std; char str[maxn]; bool flag; int num[maxn], sign[maxn], len; char s[5]= " *+-"; bool judg

UVa 817 According to Bartjens (暴力,DFS)

题意:给出一个数字组成的字符串,然后在字符串内添加三种运算符号 * + - ,要求输出所有添加运算符并运算后结果等于2000的式子. 所有数字不能有前导0, 且式子必须是合法的. 析:这个题很明显的暴力,因为最长才9位数字,也就是最多有8个位置位置可能插符号,当然实际并没有那么多,所以直接暴力就行,也不用优化,直接暴就行. 就是DFS,在每个位置考虑四种情况,*,+,-,或者不放,最后再一个一个的判断是不是等于2000就好,注意这个题有一个坑,我也不知道是哪个数据, 也没有想到,就是一个没有用运

UVa 817 According to Bartjens 题解

难度:β 建议用时:40 min 实际用时:4 h 题目:?? 代码:?? 这题有两个坑点首先要注意: 1)对于 "2000=" 要特判.应该判为 "IMPOSSIBLE" 2)枚举顺序为 "*+-" 然后是数字. 好了.这题的 DFS 过程很简单了.主要的是怎样计算一个字符串多项式(不带除号的). 代码链接:??(这里我把除号带上了,原理跟减号一样的) 从最简单的加法开始. 1+2+3 怎样计算上面的式子? 我选择用递归. 从左到右(不是遍历,

uva 817(dfs)

题意:给出一个数字组成的字符串,然后在字符串内添加三种运算符号 * + - ,要求输出所有添加运算符并运算后结果等于2000的式子. 所有数字不能有前导0,且式子必须是合法的. 题解:字符串长度25左右,可以暴力,用dfs搜索所有可能的分割情况,并在每次分割的字符后添加三种运算符,然后递归到最后一个字符拿去判断,先用栈把所有分割字符串得到的数字压栈,同时优先运算'*',然后再从左到右计算看结果是否为2000,注意2000=是IMPOSSIBLE... #include <stdio.h> #i

【习题 8-17 UVA - 11536】Smallest Sub-Array

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 尺取法. 考虑一个1..i的窗口. 里面在到达了i位置的时候恰好有1..k这些数字了. 为了更接近答案. 显然可以试着让左端点变成2.(如果还能有1..k这些数字的话. 所以有1..k这些数字之后.就让左端点尽可能往右. 然后尝试更新答案. 然后让右端点右移. 重复上述过程. [代码] #include <bits/stdc++.h> #define ll long long #define rep1(i,a,b) for (

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f

[UVa] Palindromes(401)

UVA - 401 Palindromes Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDED