Problem I
23 Out of 5
Input: standard input
Output: standard output
Time Limit: 1 second
Memory Limit: 32 MB
Your task is to write a program that can decide whether you can find an arithmetic expression consisting of five given numbers (1<=i<=5) that will yield the value 23.
For this problem we will only consider arithmetic expressions of the following from:
where : {1,2,3,4,5} -> {1,2,3,4,5} is a bijective function
and {+,-,*} (1<=i<=4)
The Input consists of 5-Tupels of positive Integers, each between 1 and 50.
Input is terminated by a line containing five zero's. This line should not be processed.
For each 5-Tupel print "Possible" (without quotes) if their exists an arithmetic expression (as described above) that yields 23. Otherwise print "Impossible".
1 1 1 1 1
1 2 3 4 5
2 3 5 7 11
0 0 0 0 0
Impossible
Possible
Possible
Thomas Strohmann
译文:
你的任務是寫一個程式,看看是否能在5個數字間插入一些運算子使得結果為23。
考慮以下的運算式結果是否可能等於23。
(((a1 O1 a2) O2 a3) O3 a4) O4 a5
在這裡a1~a5為5個給你的整數(順序可以隨便排列,但一定都要出現一次),O1~O4為運算子,內容為{+,-,*}其中一個。如果你還不清楚的話,以下面的例子來說明:
輸入5個整數2,3,5,711
你可以找到有一組運算式 (((11*3)-5)+2)-7=23,所以輸出Possible。(當然,可以得到23的答案的運算式可能不只一組)
若輸入的5個整數為1,1,1,1,1
那你就找不到任一種運算式的組合可以使答案為23。所以輸出Impossible。
Input
每一測試資料一列,有5個整數。每個整數均介於0到50之間。當輸入為5個0時代表輸入結束。測試資料總共不會超過25列。
Output
根據輸入的5個整數,判斷是否可能找到使其答案為23的運算式。請參考Sample Output
#include <iostream> #include <cstring> #include <cstdio> #include <ctime> #include <algorithm> using namespace std; int num[5]; int vis[5]; char flag2[3]={'+','-','*'}; int vis2[3]; int temp[5]; char calSignal[4]; bool ans=false; void init() { ans = false; memset(num, 0, sizeof(num)); memset(vis, 0, sizeof(vis)); memset(vis2, 0, sizeof(vis2)); } bool cal() { int value=0; for(int i=0; i < 4; i++) { switch(calSignal[i]) { case '+': { if(i==0) value = temp[i]+temp[i+1]; else value += temp[i+1]; break; } case '-': { if(i==0) value = temp[i]-temp[i+1]; else value -= temp[i+1]; break; } case '*':{ if(i==0) value = temp[i]*temp[i+1]; else value *= temp[i+1]; break; } } } if(value==23 || value==-23) return true; return false; } // 同时遍历两种可能性 TLE void f(int number, int signal) { if(ans) return ; if(number==4 && signal==3) { if(cal()) ans = true; return ; } for(int i=0; i < 5; i++) { if(!vis[i]) { vis[i]=1; temp[number] = num[i]; f(number+1, signal); vis[i]=0; } } for(int i=0; i < 3; i++) { if(!vis2[i]) { vis2[i]=1; calSignal[signal] = flag2[i]; f(number, signal+1); vis2[i] = 0; } } } void dfs(int length, int sum) { if(length==5) { if(sum==23) ans = true; return ; } sum += num[length]; dfs(length+1, sum); sum -= num[length]; if(ans) return; sum -= num[length]; dfs(length+1, sum); sum += num[length]; if(ans) return; sum *= num[length]; dfs(length+1, sum); sum /= num[length]; if(ans) return ; } void solve() { sort(num, num+5); do{ dfs(1, num[0]); if(ans) return ; }while(next_permutation(num, num+5)); } bool read() { for(int i=0; i < 5; i++) { cin >> num[i]; if(num[i]==0) return false; } return true; } int main() { // freopen("in.txt","r",stdin); while(1) { init(); bool flag = read(); if(flag) { solve(); if(ans) cout << "Possible" << endl; else cout << "Impossible" << endl; }else break; } // printf("%.2lf\n", (double)clock()/CLOCKS_PER_SEC); return 0; }