計算24點問題,有輸出方案

24點遊戲:

       24點是一種益智遊戲,24點是把4個整數(一般是正整數)通過加減乘除以及括號運算,使最後的計算結果是24的一個數學遊戲,24點可以考驗人的智力和數學敏感性,它能在遊戲中提高人們的心算能力。
       24點通常是使用撲克牌來進行遊戲的,一副牌中抽去大小王后還剩下52張(如果初練也可只用1~10這40張牌),任意抽取4張牌(稱爲牌組),用加、減、乘、除(可加括號)把牌面上的數算成24。每張牌必須只能用一次,如抽出的牌是3、8、8、9,那麼算式爲(9-8)×8×3或3×8÷(9-8)或(9-8÷8)×3等。(摘自百度百科)


算法思路:

因爲有4個數,所以可以用暴力搜索所有可能情況的方式。但注意4個數的組合方式有兩種:

一種是用一個數和剩下的一個數進行運算,得到的結果再和下一個數運算,一個一個數的運算得到24;

另一種是用兩個數運算得到一個結果,用另兩個數得到第二個結果,兩個結果之間再運算得到24.

我是用廣搜做的,也練了一下輸出方案,具體看代碼。如果想看到所有的方案,把兩個找到結果地方的break和return給註釋掉,就可以了(會有重複的,懶得改了。。。)

代碼:

#include<stdio.h>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define eps 1e-6
struct node{
	double ans;
	int State;
	int op[4];
	int ch[5];
	int p;
};
int a[4];
void output(node x){
	char s[30]={};
	int l = 14,r = 15;
	s[r++] = x.ch[0]+'0';
	for (int i = 1; i < 4; i++)
	{	
		switch(x.op[i])
		{
			case( 0 ):s[r++]='+';s[r++]=x.ch[i]+'0';break;
			case( 1 ):s[r++]='-';s[r++]=x.ch[i]+'0';break;
			case( 2 ):s[l--]='-';s[l--]=x.ch[i]+'0';break;
			case( 3 ):s[r++]='*';s[r++]=x.ch[i]+'0';break;
			case( 4 ):s[l--]='/';s[l--]=x.ch[i]+'0';break;
			case( 5 ):s[r++]='/';s[r++]=x.ch[i]+'0';break;
			default:break;
		}
		if(i<3){
			s[l--] = '(';
			s[r++] = ')';
		}
	}
	printf("一種可以的計算方案:\t");
	for (int i = l+1; i < r; i++)
	{
		if(s[i] > '0')printf("%d",s[i]-'0');
		else printf("%c",s[i]);
	}printf("\n");
	return ;
}
void print(char s[]){
	for (int i = 0; i < 5; i++)
	{
		if(s[i] > '0')printf("%d",s[i]-'0');
		else printf("%c",s[i]);
	}
}
bool check(int s,int d,int f,int g){
	int flag = 0;
	double h1,h2;
	double ans;
	char x[6]={},y[6]={};
	x[0] = y[0] = '(';
	x[4] = y[4] = ')';
	x[5] = y[5] = '\0';
	for (int j = 0; j < 6; j++)
	{
		if(j==0)			    {h1 = s + d; x[1] = s+'0';x[2] = '+';x[3] = d+'0';}
		else if(j==1)			{h1 = s - d; x[1] = s+'0';x[2] = '-';x[3] = d+'0';}
		else if(j==2)			{h1 = d - s; x[1] = d+'0';x[2] = '-';x[3] = s+'0';}
		else if(j==3)			{h1 = d * s; x[1] = d+'0';x[2] = '*';x[3] = s+'0';}
		else if(j==4 && s!=0)	{h1 =1.0*d/s;x[1] = d+'0';x[2] = '/';x[3] = s+'0';}
		else if(j==5)			{h1 =1.0*s/d;x[1] = s+'0';x[2] = '/';x[3] = d+'0';}
		else continue;

		for (int i = 0; i < 6; i++)
		{
			if(i==0)			    {h2 = f + g; y[1] = f+'0';y[2] = '+';y[3] = g+'0'; }
			else if(i==1)			{h2 = f - g; y[1] = f+'0';y[2] = '-';y[3] = g+'0'; }
			else if(i==2)			{h2 = g - f; y[1] = g+'0';y[2] = '-';y[3] = f+'0'; }
			else if(i==3)			{h2 = g * f; y[1] = g+'0';y[2] = '*';y[3] = f+'0'; }
			else if(i==4 && f!=0)	{h2 =1.0*g/f;y[1] = g+'0';y[2] = '/';y[3] = f+'0';}
			else if(i==5)			{h2 =1.0*f/g;y[1] = f+'0';y[2] = '/';x[3] = g+'0';}
			else continue;

			for (int k = 0; k < 6; k++)
			{
				if(k==0)ans = h1 + h2;
				else if(k==1)ans = h1 - h2;
				else if(k==2)ans = h2 - h1;
				else if(k==3)ans = h1 * h2;
				else if(k==4 && h1!=0)ans = h2/h1;
				else if(k==5 && h2!=0)ans = h1/h2;

				if(fabs(ans-24.0)<eps){
					printf("一種可以的計算方案:\t");
					switch (k)
					{
						case(0):print(x);printf("+");print(y);break;
						case(1):print(x);printf("-");print(y);break;
						case(3):print(x);printf("*");print(y);break;
						case(5):print(x);printf("/");print(y);break;
														  
						case(4):print(y);printf("/");print(x);break;
						case(2):print(y);printf("-");print(x);break;
					default:
						break;
					}
					printf("\n");
					flag = 1;
					return 1;
				}
			}
		}
	}
	if(flag)return 1;
	return 0;
}
queue<node>Q;
int main(){
	while(scanf("%d%d%d%d",&a[0],&a[1],&a[2],&a[3])!=EOF){
		node st;
		while(!Q.empty())Q.pop();
		for (int i = 0; i < 4; i++)
		{
			st.ans = a[i];
			st.State = 1<<i;
			st.p = 0;
			st.op[0] = 7;
			st.ch[0] = a[i];
			Q.push(st);
		}
		node nows,next;
		int flag = 0;
		while(!Q.empty()){
			nows = Q.front();
			if(fabs(nows.ans-24.0) < eps  && nows.State == 15){
				flag = 1;
				output(nows);
				break;
			}
			for (int i = 0; i < 4; i++)
			{
				if((nows.State & (1<<i)) == 0)
				{
					next.State = nows.State | (1<<i);
					for (int j = 0; j < 6; j++)
					{
						if(j==0)next.ans = nows.ans + a[i];
						else if(j==1)next.ans = nows.ans - a[i];
						else if(j==2)next.ans = a[i] - nows.ans;
						else if(j==3)next.ans = a[i] * nows.ans;
						else if(j==4 && nows.ans!=0)next.ans = a[i]/nows.ans;
						else if(j==5)next.ans = nows.ans/a[i];
						else continue;
						next.p = nows.p + 1;
						for (int k = 0; k < next.p; k++){
							next.op[k] = nows.op[k];
							next.ch[k] = nows.ch[k];
						}
						next.ch[next.p] = a[i];
						next.op[next.p] = j;
						Q.push(next);
					}
				}
			}
			Q.pop();
		}
		if(flag)	/*printf("yes\n")*/;
		else{
			//多1種情況 :某兩個操作得到一個結果,另兩個操作得到一個結果,二者組合得到一個結果。
			//如 12,12,12,10
			if(check(a[0],a[1],a[2],a[3])||check(a[0],a[2],a[1],a[3])||check(a[0],a[3],a[1],a[2]))flag = 1;
			if(flag)/*printf("yes\n")*/;
			else printf("no\n");
		}
	}
	return 0;
}




一些數據:

2 5 5 10

3 3 7 7

4 4 7 7

3 7 9 13

6 9 9 10

12 12 12 10

9 11 12 12

發佈了119 篇原創文章 · 獲贊 10 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章