洛谷【P1236】算24点

我对状态空间的理解:https://www.cnblogs.com/AKMer/p/9622590.html

题目传送门:https://www.luogu.org/problemnew/show/P1236

(24)点应该是大家耳熟能详的游戏了……

这题(SPJ),要求把两个要运算的数字较大的放在前面输出……

然后爆搜数字顺序和运算符就可以了……

真~暴力美学

时间复杂度:(O(4!*4^3))

空间复杂度:(O(n))

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

bool bo[5];
int a[5],sta[5],sign[4],fake[5];

int read() {
	int x=0,f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
	return x*f;
}

void print() {
	int sum=sta[1];
	for(int i=2;i<=4;i++) {
		if(sum<sta[i])swap(sum,sta[i]);
		if(sign[i-1]==1)printf("%d+%d=%d
",sum,sta[i],sum+sta[i]),sum+=sta[i];
		if(sign[i-1]==2)printf("%d-%d=%d
",sum,sta[i],sum-sta[i]),sum-=sta[i];
		if(sign[i-1]==3)printf("%d*%d=%d
",sum,sta[i],sum*sta[i]),sum*=sta[i];
		if(sign[i-1]==4)printf("%d/%d=%d
",sum,sta[i],sum/sta[i]),sum/=sta[i];
	}
}//输出

void check() {
	memcpy(fake,sta,sizeof(fake));
	int now=fake[1];
	for(int i=2;i<=4;i++) {
		if(now<fake[i])swap(now,fake[i]);//记得要把大的数字放在前面判
		if(sign[i-1]==1)now=now+fake[i];
		if(sign[i-1]==2)now=now-fake[i];
		if(sign[i-1]==3)now=now*fake[i];
		if(sign[i-1]==4) {
			if(fake[i]==0)return;
			if(now%fake[i])return;
			now/=fake[i];
		}
	}
	if(now==24) {print();exit(0);}
}//判断是否可以算出24

void make_sign(int id) {
	if(id==3) {check();return;}
	for(int i=1;i<=4;i++)
		sign[id+1]=i,make_sign(id+1);
}//搜完运算符就判是否可行

void dfs(int id) {
	if(id==4) {
		for(int i=1;i<=4;i++)
			sign[1]=i,make_sign(1);
		return;
	}//搜完数字搜运算符
	for(int i=1;i<=4;i++)
		if(!bo[i]) {
			bo[i]=1,sta[id+1]=a[i];
			dfs(id+1);
			bo[i]=0;
		}//爆搜数字
}

int main() {
	a[1]=read(),a[2]=read();
	a[3]=read(),a[4]=read();//读入四个数
	for(int i=1;i<=4;i++) {
		bo[i]=1;sta[1]=a[i];
		dfs(1);
		bo[i]=0;//爆搜
	}puts("No answer!");//如果爆搜出不了结果就No answer!
	return 0;
}
原文地址:https://www.cnblogs.com/AKMer/p/9636647.html