为了培养小孩的计算能力,大人们经常给小孩玩这样的游戏:从1付扑克牌中任意抽出4张扑克,要小孩用“+”、“-”、“×”、“÷”和括号组成一个合法的表达式,并使表达式的值为24点。这种游戏就是所谓的“24点游戏”。请你编程求出对于给出的任意4个正整数a、b、c、d,请你编程求出这4个整数能组成多少个值为24的不同表达式。
Input
输入共一行,为4个正整数a、b、c、d (0<=a,b,c,d<=100)
Output
输出由a、b、c、d组成的值为24表达式个数,如没有,输出0。
Sample Input
5 5 5 5
Sample Output
1
Hint
解题思路:
先枚举数字的顺序
再枚举每个运算符号
然后是枚举运算先后 即怎么加括号
但是方案数并不能这么开心的得到
所以哈希一下,最后判个重
全靠暴力 锻炼暴力能力!!!
AC代码:
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<map>
#include<set>
using namespace std;
const double eps=1e-9;
int a[5],r[5],v[5],tot,hash[8000];
bool book[5];
void insert(int x1,int x2,int x3,int x4,int x5,int x6,int x7)
{
hash[++tot]=x1|x2<<3|x3<<6|x4<<9|x5<<12|x6<<15|x7<<18;//<<的优先级比|高,<<3等于乘2的3次方
}
double opt(double x,double y,int o)
{
if(o==0)return x+y;
if(o==1)return x-y;
if(o==2)return x*y;
return x/y;
}
bool can(int x,int y)
{
if(x==0) return y>1;
if(x==2) return y<2;
return 1;
}
void check()
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
for(int k=0;k<4;k++)
{
bool c1=can(k,j),c2=can(j,i);
if(abs(opt(opt(opt(a[v[1]],a[v[2]],i),a[v[3]],j),a[v[4]],k)-24)<eps)
insert(r[v[1]],r[v[2]],i+4,r[v[3]],j+4,r[v[4]],k+4);
if(c1&&abs(opt(opt(a[v[1]],a[v[2]],i),opt(a[v[3]],a[v[4]],j),k)-24)<eps)
insert(r[v[1]],r[v[2]],i+4,r[v[3]],r[v[4]],j+4,k+4);
if(c2&&abs(opt(opt(a[v[1]],opt(a[v[2]],a[v[3]],i),j),a[v[4]],k)-24)<eps)
insert(r[v[1]],r[v[2]],r[v[3]],i+4,j+4,r[v[4]],k+4);
if(c1&&abs(opt(a[v[1]],opt(opt(a[v[2]],a[v[3]],i),a[v[4]],j),k)-24)<eps)
insert(r[v[1]],r[v[2]],r[v[3]],i+4,r[v[4]],j+4,k+4);
if(c1&&c2&&abs(opt(a[v[1]],opt(a[v[2]],opt(a[v[3]],a[v[4]],i),j),k)-24)<eps)
insert(r[v[1]],r[v[2]],r[v[3]],r[v[4]],i+4,j+4,k+4);
}
}
}
}
void dfs(int step)
{
if(step>4)
{
check();
return;
}
for(int i=0;i<4;i++)
{
if(book[i]==0)
{
book[i]=1;
v[step]=i;
dfs(step+1);
book[i]=0;
}
}
}
int main()
{
for(int i=0;i<4;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
r[i]+=a[i]<a[j];
}
}
dfs(1);
sort(hash+1,hash+1+tot);
int ans=0;
if(tot) ans=1;
for(int i=2;i<=tot;i++)
{
if(hash[i]^hash[i-1]) ans++;//结果不同
}
printf("%d\n",ans);
return 0;
}
/*
5 5 5 5
1
*/