UVA - 10344 23 out of 5(回溯+全排列)

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)     

Input

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.

Output

For each 5-Tupel print "Possible" (without quotes) if their exists an arithmetic expression (as described above) that yields 23. Otherwise print "Impossible".

Sample Input

1 1 1 1 1 
1 2 3 4 5 
2 3 5 7 11 
0 0 0 0 0 

Sample Output

Impossible 
Possible 
Possible 


题意:
输入5个整数,按照某种顺序排列后依次进行+, -或者*,使得最终结果为23。判断是否有解。

解析:用回溯法+全排列来做。
先用全排列下标枚举出所有的组合,然后用回溯,枚举出经过 + - * 任意组合后所有可能的解,如果满足 = 23 就输出possible,如果全部枚举都找不到就输出impossible。


#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 5;
int a[N];
int t[N];
bool flag;
void dfs(int v,int sum) {
	if(v == 5 ) {
		if(sum == 23) {
			flag = true;
		}
		return ;
	}
	if(!flag) {
		dfs(v+1,sum*a[t[v]]);
	}
	if(!flag) {
		dfs(v+1,sum+a[t[v]]);
	}
	if(!flag) {
		dfs(v+1,sum-a[t[v]]);
	}
}
int main() {
	while( scanf("%d%d%d%d%d",&a[0],&a[1],&a[2],&a[3],&a[4]) != EOF) {
		if(!a[0] && !a[1] && !a[2] && !a[3] && !a[4]) {
			break;
		}
		for(int i = 0; i < N; i++) {
			t[i] = i;
		}
		do{
			flag = false;
			dfs(1,a[t[0]]);
			if(flag) {
				break;
			}
		}while(next_permutation(t,t+5));
		if(flag) {
			printf("Possible\n");
		}else {
			printf("Impossible\n");
		}
	}
	return 0;
}


你可能感兴趣的:(out,uva,of,5,23)