Hint

33 33 88 88

就可以构造出 8÷(3–8÷3)=24

题解:求24点,暴力搜索下就好,刚开始我想着全排列下,然后按照顺序来进行,但是思路明显不完善,然后看了大神的,

大神是延长数组存放当前运算的解,vis记录是否用过,思路很巧妙;很简单就A过了;

代码:

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

const int INF=0x3f3f3f3f;

#define SI(x) scanf("%d",&x)

#define PI(x) printf("%d",x)

#define P_ printf(" ")

#define mem(x,y) memset(x,y,sizeof(x))

typedef long long LL;

int flot;

double a[110];

int vis[110];

/*void dfs(int pos,double cur);

void ary(int num){

if(flot)return;

if(num==4){

// for(int i=0;i<4;i++)printf("%d ",ans[i]);puts("");

dfs(1,ans[0]);

return;

}

for(int i=0;i<4;i++){

if(vis[i])continue;

ans[num]=a[i];

vis[i]=1;

ary(num+1);

vis[i]=0;

}

}

*/

void dfs(int usd,int tp){

if(flot)return;

if(usd==4){

if(abs(a[tp-1]-24)<1e-8)flot=1;

return;

}

/*

dfs(pos+1,cur+ans[pos]);

dfs(pos+1,cur-ans[pos]);

dfs(pos+1,cur*ans[pos]);

dfs(pos+1,cur/ans[pos]);

dfs(pos+1,-cur*ans[pos]);

dfs(pos+1,-cur/ans[pos]);

dfs(pos+1,ans[pos]/cur);

dfs(pos+1,ans[pos]/cur);

*/

for(int i=0;i

if(vis[i])continue;

vis[i]=1;

for(int j=i+1;j

if(vis[j])continue;

vis[j]=1;

a[tp]=a[i]+a[j];dfs(usd+1,tp+1);

a[tp]=a[i]*a[j];dfs(usd+1,tp+1);

a[tp]=a[i]-a[j];dfs(usd+1,tp+1);

a[tp]=a[j]-a[i];dfs(usd+1,tp+1);

if(a[i]!=0){

a[tp]=a[j]/a[i];dfs(usd+1,tp+1);

}

if(a[j]!=0){

a[tp]=a[i]/a[j];dfs(usd+1,tp+1);

}

vis[j]=0;

}

vis[i]=0;

}

}

int main(){

int T;

SI(T);

while(T--){

for(int i=0;i<4;i++)scanf("%lf",&a[i]);

flot=0;

mem(vis,0);

dfs(1,4);

if(flot)puts("yes");

else puts("no");

}

return 0;

}

速算24点

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4250 Accepted Submission(s): 1044

Problem Description

速算24点相信绝大多数人都玩过。就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13)。要求只用'+','-','*','/'运算符以及括号改变运算顺序,使得最终运算结果为24(每个数必须且仅能用一次)。游戏很简单,但遇到无解的情况往往让人很郁闷。你的任务就是针对每一组随机产生的四张牌,判断是否有解。我们另外规定,整个计算过程中都不能出现小数。

Input

每组输入数据占一行,给定四张牌。

Output

每一组输入数据对应一行输出。如果有解则输出"Yes",无解则输出"No"。

Sample Input

A 2 3 6

3 3 8 8

Sample Output

Yes

No

题解:跟上题不同的是,这个是字符输入,而且,是整除的;注意10的读入。。。

虽然写过,但是比赛出到还是不会。。。这个题思路就是dfs,a[tp - 1]代表当前usd的个数的计算值。

代码:

#include

#include

#include

#include

#include

#include

using namespace std;

int a[1010];

int vis[1010];

int ans;

void dfs(int usd, int tp){

if(ans)return;

if(usd == 4){

if(a[tp - 1] == 24)ans = 1;

return;

}

for(int i = 0; i < tp; i++){

if(vis[i])continue;

vis[i] = 1;

for(int j = i + 1; j < tp; j++){//注意应该从i + 1开始,可以让时间减少一般否则会超时;

if(vis[j])continue;

vis[j] = 1;

a[tp] = a[i] + a[j];dfs(usd + 1, tp + 1);

a[tp] = a[i] - a[j];dfs(usd + 1, tp + 1);

a[tp] = a[j] - a[i];dfs(usd + 1, tp + 1);

a[tp] = a[i] * a[j];dfs(usd + 1, tp + 1);

if(a[j] != 0 && a[i] % a[j] == 0){

a[tp] = a[i] / a[j];dfs(usd + 1, tp + 1);

}

if(a[i] != 0 && a[j] % a[i] == 0){

a[tp] = a[j] / a[i];dfs(usd + 1, tp + 1);

}

vis[j] = 0;

}

vis[i] = 0;

}

}

int main(){

char s[4][4];

while(~scanf("%s %s %s %s",s[0],s[1],s[2],s[3])){

for(int i =0;i < 4;i++){

if(strlen(s[i]) == 2)a[i] = 10;

else if(s[i][0] == 'A')a[i] = 1;

else if(s[i][0] == 'J')a[i] = 11;

else if(s[i][0] == 'Q')a[i] = 12;

else if(s[i][0] == 'K')a[i] = 13;

else a[i] = s[i][0] - '0';

}

ans = 0;

memset(vis, 0, sizeof(vis));

dfs(1, 4);

if(ans)

puts("Yes");

else

puts("No");

}

return 0;

}