1. 程式人生 > >算24【遞迴】

算24【遞迴】

題目連結:https://cn.vjudge.net/problem/OpenJ_Bailian-2787

題目描述:

給出4個小於10個正整數,你可以使用加減乘除4種運算以及括號把這4個數連線起來得到一個表示式。現在的問題是,是否存在一種方式使得得到的表示式的結果等於24。 

這裡加減乘除以及括號的運算結果和運算的優先順序跟我們平常的定義一致(這裡的除法定義是實數除法)。 

比如,對於5,5,5,1,我們知道5 * (5 – 1 / 5) = 24,因此可以得到24。又比如,對於1,1,4,2,我們怎麼都不能得到24。 

Input

輸入資料包括多行,每行給出一組測試資料,包括4個小於10個正整數。最後一組測試資料中包括4個0,表示輸入的結束,這組資料不用處理。

Output

對於每一組測試資料,輸出一行,如果可以得到24,輸出“YES”;否則,輸出“NO”。

Sample Input

5 5 5 1
1 1 4 2
0 0 0 0

Sample Output

YES
NO

 

沒啥好說的,一個簡單的遞迴

AC程式碼: 

#include <iostream>
#include <cmath>
#define MIN 1e-6
using namespace std;
const int n = 4;
bool su24(double a[],int num)
{
	cout << a[num-1] << endl;
	if( num == 1) {
		if(fabs(a[0] - 24) < MIN)
			return true;
		else
			return false;
	}

	double b[num];			
	for(int i=0;i<num;i++) {
		for(int j=i+1;j<num;j++) {
			int k = 0;
			for(int z=0;z<num;z++)
				if(z != i && z!= j)
					b[k++] = a[z];

			// 把n個數的操作轉化為n-1個數的操作  *** 
			b[k] = a[i]+a[j];
			if(	su24(b,k+1))
				return true;
			b[k] = a[i]-a[j];
			if( su24(b,k+1))
				return true;
			b[k] = a[i]*a[j];
			if( su24(b,k+1))
				return true;
			if( a[i] != 0) {
				b[k] = a[j]/a[i];
				if( su24(b,k+1))
					return true;
			}
			if( a[j] != 0) {
				b[k] = a[i]/a[j];
				if( su24(b,k+1))
					return true;
			}
		}
	}
	return false;
}
int main()
{
	double a[n];
	while(cin >> a[0] >> a[1] >> a[2] >> a[3] && a[0]!=0 && a[1]!=0 && a[2]!=0 && a[3]!=0) 
	{
		if( su24(a,n))
			cout << "YES" << endl;
		else
			cout << "NO" << endl;

	}
}