24点问题(穷举法/C++)



算24点(point24)
【问题描述】
 几十年前全世界就流行一种数字游戏,至今仍有人乐此不疲.在中国我们把这种游戏称为“算24点”。您作为游戏者将得到4个1~9之间的自然数作为操作数,而您的任务是对这4个操作数进行适当的算术运算,要求运算结果等于24。
 您可以使用的运算只有:+,-,*,/,您还可以使用()来改变运算顺序。注意:所有的中间结果须是整数,所以一些除法运算是不允许的(例如,(2*2)/4是合法的,2*(2/4)是不合法的)。下面我们给出一个游戏的具体例子:
 若给出的4个操作数是:1、2、3、7,则一种可能的解答是1+2+3*7=24。
【输入】
 只有一行,四个1到9之间的自然数。
【输出】
 如果有解的话,只要输出一个解,输出的是三行数据,分别表示运算的步骤。其中第一行是输入的两个数和一个运算符和运算后的结果,第二行是第一行的结果和一个输入的数据、运算符、运算后的结果;第三行是第二行的结果和输入的一个数、运算符和“=24”。如果两个操作数有大小的话则先输出大的。
 如果没有解则输出“No answer!”
【样例】
 point24.in  

1 2 3 7

point24.out    

2+1=3
7*3=21
21+3=24

总可能情况很少,只有4个数字和4种符号(括号),直接采用穷举法,但要稍微处理下叠加括号问题。

但是这里发现只有括号内有加减法运算,括号外有乘除法运算时,该括号才有意义,因此分析后发现只有4个数字时,叠加括号是没有意义的(这里说的不太清楚,自己稍微推一下就知道了)。代码如下

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;

int a1[5],b1[4];

void gol(char f,int k,int num)
{
	if (f=='a') for(int i=k;i<=num;i++) a1[i-1]=a1[i];
	if (f=='b') for(int i=k;i<=num;i++) b1[i-1]=b1[i];
}

int cal(int a,int b,int num)
{
	if (num==0) return a+b;
	if (num==1) return a-b;
	if (num==2) return a*b;
	if (num==3) return a/b;
}

string cha(int a)
{
	string p;
	p="";
	while(a>0)
	{
		p=(char)(a%10)+p;
		a/=10;
	}
	return p;
}

string chaf(int a)
{
	if (a==0) return "+";
	if (a==1) return "-";
	if (a==2) return "*";
	if (a==3) return "/";
}

int main()
{
	string ans[5];
	int a[5],b[5],i,anum,bnum;
	for(i=1;i<=4;i++) cin >> a[i];
	memset(b,0,sizeof(b));
	bool f[4];
	int s,j,d[4],ansnum;
	while(b[0]==0)
	{
		/*for(i=1;i<=3;i++)
		{
			cout << b[i]  << " ";
		}*/
		//cout << endl;
		memset(f,0,sizeof(f));
		s=0;
		for(i=1;i<=3;i++)
		{
			if (b[i]==1 || b[i]==0)
			{
				if (b[i-1]==3 || b[i-1]==2 || b[i+1]==3 || b[i+1]==2)
				{
					s++;
					d[s]=i;
				}
			}
		}
		while(f[0]==0)
		{
			for(i=1;i<=s;i++)
			{
				cout << f[i] << " ";
			}
			cout << endl;
			for(i=1;i<=4;i++) a1[i]=a[i];
			for(i=1;i<=3;i++) b1[i]=b[i];
			anum=4;bnum=3;
			for(i=1;i<=4;i++) ans[i]="";
			ansnum=0;
			j=1;
			while(j<=bnum)
			{
				if (f[j]==1)
				{
					ansnum++;
					ans[ansnum]=cha(a1[d[j]])+chaf(b1[d[j]])+chaf(a1[d[j]+1])+"=";
					a1[d[j]]=cal(a1[d[j]],a1[d[j]+1],b1[d[j]]);
					ans[ansnum]+=cha(a1[d[j]]);
					gol('a',d[j]+1,anum);
					anum--;
					gol('b',d[j]+1,bnum);
					bnum--;
				}
				j++;
			}
			j=1;
			//cout << anum  << " " << bnum << endl;
			while(j<=bnum)
			{
				if (b[j]==2 || b[j]==3)
				{
					ansnum++;
					ans[ansnum]=cha(a1[j])+chaf(b1[j])+chaf(a1[j+1])+"=";
					a1[j]=cal(a1[j],a1[j+1],b1[j]);
					ans[ansnum]+=cha(a1[j]);
					gol('a',j+1,anum);
					anum--;
					gol('b',j+1,bnum);
					bnum--;
				}
				j++;
			}
			//cout << anum  << " " << bnum << endl;
			j=1;
			while(j<=bnum)
			{
				ansnum++;
				ans[ansnum]=cha(a1[j])+chaf(b1[j])+chaf(a1[j+1])+"=";
				a1[j]=cal(a1[j],a1[j+1],b1[j]);
				ans[ansnum]+=cha(a1[j]);
				gol('a',j+1,anum);
				anum--;
				gol('b',j+1,bnum);
				bnum--;
			}
			//cout << anum  << " " << bnum << endl;
			//cout << a1[1] << endl;
			if (a1[1]==24)
			{
				for(j=1;j<=ansnum;j++)
				{
					cout << ans[j] << endl;
				}
				return 0;
			}
			j=s;
			while(f[j]==1)
			{
				f[j]==0;
				j--;
			}
			f[j]=1;
		}
		//cout << "---------------\n";
		i=3;
		while(b[i]==3)
		{
			b[i]=0;
			i--;
		}
		b[i]++;
	}
}


  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
穷举法(也为暴力搜索)是一种简单直接的解决问题的方法,它通过尝试所有可能的解决方案来找到最优解。在背包问题中,穷举法可以用来找到能够装入背包的物品组合,使得总价值最大化。 以下是使用穷举法解决背包问题的一般步骤: 1. 定义背包的容量和物品的重量、价值数组。 2. 枚举所有可能的物品组合,对于每个组合计算总重量和总价值。 3. 如果总重量小于等于背包容量,并且总价值大于当最优解,则更新最优解。 4. 继续枚举下一个物品组合,直到所有组合都被尝试过。 5. 返回最优解。 在C++中,可以使用递归函数来实现穷举法解决背包问题。下面是一个简单的示例代码: ```cpp #include <iostream> using namespace std; int max_value = 0; // 最优解的总价值 // 递归函数,用于穷举所有可能的物品组合 void exhaustiveSearch(int capacity, int weights[], int values[], int n, int cur_weight, int cur_value) { if (cur_weight <= capacity && cur_value > max_value) { max_value = cur_value; } if (n == 0) { return; } // 不选择当物品 exhaustiveSearch(capacity, weights, values, n - 1, cur_weight, cur_value); // 选择当物品 exhaustiveSearch(capacity, weights, values, n - 1, cur_weight + weights[n - 1], cur_value + values[n - 1]); } int main() { int capacity = 10; // 背包容量 int weights[] = {2, 3, 4, 5}; // 物品重量数组 int values[] = {3, 4, 5, 6}; // 物品价值数组 int n = sizeof(weights) / sizeof(weights[0]); // 物品数量 exhaustiveSearch(capacity, weights, values, n, 0, 0); cout << "最优解的总价值为:" << max_value << endl; return 0; } ``` 这段代码中,我们定义了一个全局变量`max_value`来保存最优解的总价值。`exhaustiveSearch`函数用于递归地穷举所有可能的物品组合,并更新最优解。在`main`函数中,我们定义了背包的容量、物品的重量和价值数组,并调用`exhaustiveSearch`函数来求解最优解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值