zoukankan      html  css  js  c++  java
  • UVA817-According to Bartjens(DFS)

    Problem UVA817-According to Bartjens

    Accept: 270    Submit: 2071
    Time Limit: 1000 mSec    Memory Limit : 128MB

    Problem Description

    The wide dissemination of calculators and computers has its disadvantages. Even students in technical disciplines tend to exhibit a surprising lack of calculating ability. Accustomed to the use of calculators and computers, many of them are unable to make calculations like 7* 8 mentally or like 13 * 17 using pencil and paper. We all know, but who cares? Professor Bartjens [Willem Bartjens (1569-1638) was the author of Cijferinge, a much used Dutch textbook on arithmetic. The phrase “...according to Bartjens” (uttered following a calculation) made his name immortal.] cares. Professor Bartjens is a bit old fashioned. He decided to give his students some training in calculating without electronic equipment by creating a collection of calculation problems, (like 2100 - 100 = ...). To simplify grading the problems, he constructed them so that almost all of them had 2000 as an answer. Not all of them, of course. His students would be smart enough to recognize the pattern, and fill in 2000 everywhere without further thinking. Unfortunately Professor Bartjens’ printer driver turned out to be even more old-fashioned than the professor himself, and it could not interface with his new printer. Inspecting the printed problems, he soon recognized the pattern: none of 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 file had disappeared. So Professor Bartjens has another problem: what were his original problems? Given the fact that the answer (most likely) should be 2000, the line 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 the problems:
    • He is sure that whenever he wrote down a number (other than 0), it would not start with a zero. So 2*10*0100= could not have been one of his problems. • He also knows he never wrote the number zero as anything but 0. So he would not have a problem like 2*1000+000=. • He used only binary operators, not the unary minus or plus, so 2*-100*-10+0= was not an option either. • He used the operators ‘+’, ‘-’ and ‘*’ only, avoiding the operator ‘/’ (after all, they were first year students). • He knew all problems followed the usual precedence and associativity rules.
    You are to help Professor Bartjens recover his problem set by writing a program that when given a row of digits, insert one or more of the operators ‘+’, ‘-’ and ‘*’ in such a way that the value of the resulting expression equals 2000.

    Input

    The input consists of one or more test cases. Each test case is a single line containing n digits (’0’...’9’), 1 ≤ n ≤ 9, followed by an equal sign. There will not be any blanks embedded in the input, but there may be some after the equal sign. The last test case is followed by a line containing only the equal sign. This line should not be processed.

     Output

     For each test case, print the word ‘Problem’, then the number of the case, then all possible ways of inserting operators in the row of digits such that the resulting expression has the value 2000, subject to Professor Bartjens memory of how he wrote the problems. Use the format shown below. If there is more than one possible problem, they may be written in any order, but no problem may appear more than once in the list. Each possible problem should be on a new line, indented 2 spaces. If there is no solution the answer ‘IMPOSSIBLE’ should be printed, indented 2 spaces.

     

     Sample Input

    2100100=
    77=
    =

     Sample Output

    Problem 1

      2100-100=

      2*100*10+0=

      2*100*10-0=

    Problem 2

      IMPOSSIBLE

    题解:这个题主题框架很简单,本来应该是个水题,但是在写表达式求值的时候出现了不少小问题,调了很长时间。基本功还是不扎实。

    考虑在哪个空位放哪个符号,DFS即可,没有什么太明显的可以剪枝得地方。

      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 const int maxn = 20;
      6 char str[maxn];
      7 char table[] = { '*','+','-' };
      8 int n, res[maxn];
      9 vector<string> ans;
     10 
     11 
     12 void cal(int len) {
     13     stack<int> sta;
     14     int cnt = 0;
     15     char tmp[maxn];
     16     for (int i = 0; i < len; i++) {
     17         if (res[i] == 3) {
     18             tmp[i] = str[cnt++];
     19         }
     20         else tmp[i] = table[res[i]];
     21     }
     22     tmp[len] = '=';
     23     tmp[len+1] = '';
     24     //printf("%s
    ", tmp);
     25 
     26     int a, b;
     27     char *head = tmp;
     28     char ch;
     29     while (true) {
     30         sscanf(head, "%d%c", &a, &ch);
     31         if (a != 0 && *head == '0') return;
     32         sta.push(a);
     33         if (ch == '=') break;
     34         head = strchr(head, ch) + 1;
     35         
     36         if (ch == '*') {
     37             while (ch == '*') {
     38                 sscanf(head, "%d%c", &b, &ch);
     39                 if (b!=0 && *head == '0') return;
     40                 head = strchr(head, ch) + 1;
     41                 a = sta.top(); sta.pop();
     42                 a *= b;
     43                 sta.push(a);
     44             }
     45         }
     46         if (ch == '-') sta.push(-1);
     47         if (ch == '+') sta.push(-2);
     48         if (ch == '=') break;
     49     }
     50 
     51     int rres = 0;
     52     stack<int> ssta;
     53     while (!sta.empty()) ssta.push(sta.top()), sta.pop();
     54     while (!ssta.empty() && true) {
     55         int a = ssta.top(); ssta.pop();
     56         if (ssta.empty()) {
     57             rres = a;
     58             break;
     59         }
     60 
     61         int flag = ssta.top(); ssta.pop();
     62         int b = ssta.top(); ssta.pop();
     63         if (flag == -1) a -= b;
     64         else a += b;
     65         ssta.push(a);
     66     }
     67 
     68     if (rres == 2000) {
     69         //printf("%s
    ", tmp);
     70         string ss(tmp);
     71         ans.push_back(ss);
     72     }
     73 }
     74 
     75 void dfs(int len,int pos,int pre) {
     76     if (pos == n) {
     77         cal(len);
     78         return;
     79     }
     80 
     81     if (pre) {
     82         for (int i = 0; i < 4; i++) {
     83             res[len] = i;
     84             if (i == 3) dfs(len + 1, pos + 1, 1);
     85             else dfs(len + 1, pos, 0);
     86         }
     87     }
     88     else {
     89         res[len] = 3;
     90         dfs(len + 1, pos + 1, 1);
     91     }
     92 }
     93 
     94 void solve() {
     95     ans.clear();
     96     dfs(0,0,0);
     97 }
     98 
     99 int main()
    100 {
    101     //freopen("input.txt", "r", stdin);
    102     //freopen("output.txt", "w", stdout);
    103     int iCase = 1;
    104     while (~scanf("%s", str) && str[0] != '=') {
    105         if (strcmp(str, "2000=") == 0) {
    106             printf("Problem %d
    ", iCase++);
    107             printf("  IMPOSSIBLE
    ");
    108             continue;
    109         }
    110         n = strlen(str);
    111         n--;
    112         str[n] = 0;
    113         printf("Problem %d
    ",iCase++);
    114         solve();
    115         if (ans.size() == 0) {
    116             printf("  IMPOSSIBLE
    ");
    117         }
    118         else {
    119             vector<string>::iterator iter;
    120             for (iter = ans.begin(); iter != ans.end(); iter++) {
    121                 cout << "  " << *iter << endl;
    122             }
    123         }
    124     }
    125     return 0;
    126 }
  • 相关阅读:
    day10_发送邮件终极版
    day10_发送带附件的邮件
    day10_发送普通邮件
    day10_多线程性能测试
    day10_虚拟环境和搭建测试环境的步骤
    codeforces 877B
    codeforces 982C Cut 'em all! (dfs)
    洛谷P1171 售货员的难题 dp
    点集配对问题
    codeforces 891A Pride (数学)
  • 原文地址:https://www.cnblogs.com/npugen/p/9602152.html
Copyright © 2011-2022 走看看