列表

详情


NC20028. [HNOI2003]24点游戏

描述

为了培养小孩的计算能力,大人们经常给小孩玩这样的游戏:
从1付扑克牌中任意抽出4张扑克,要小孩用“+”、“-”、“×”、“÷”和括号组成一个合法的表达式,并使表达式的值为24点。这种游戏就是所谓的“24点游戏”。
请你编程求出对于给出的任意4个正整数a、b、c、d,请你编程求出这4个整数能组成多少个值为24的不同表达式。

输入描述

输入共一行,为4个正整数a、b、c、d (0 ≤ a,b,c,d ≤ 100)

输出描述

输出由a、b、c、d组成的值为24表达式个数,如没有,输出0。

示例1

输入:

5 5 5 5

输出:

1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 4ms, 内存消耗: 376K, 提交时间: 2020-01-25 17:50:06

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define eps 1e-7
using namespace std;
int v[4],r[4],hs[8000],p=0,ans=0;
inline void add(int v1,int v2,int v3,int v4,int v5,int v6,int v7){
    hs[++p]=(v1|v2<<3|v3<<6|v4<<9|v5<<12|v6<<15|v7<<18);
}
inline double f(double a,double b,int op){
    if (op==0) return a+b;
    if (op==1) return a-b;
    if (op==2) return a*b;
    return a/b;
}
inline bool e(int a,int b){
    if (a==0) return b>1;
    if (a==2) return b<2;
    return 1;
}
inline void check(int v1,int v2,int v3,int v4){
    for (int i=0;i<4;i++)
        for (int j=0;j<4;j++)
            for (int k=0;k<4;k++){
                bool e1=e(k,j),e2=e(j,i);
                if (fabs(f(f(f(v[v1],v[v2],i),v[v3],j),v[v4],k)-24)<eps)
                    add(r[v1],r[v2],i+4,r[v3],j+4,r[v4],k+4);
                if (e1&&fabs(f(f(v[v1],v[v2],i),f(v[v3],v[v4],j),k)-24)<eps)
                    add(r[v1],r[v2],i+4,r[v3],r[v4],j+4,k+4);
                if (e2&&fabs(f(f(v[v1],f(v[v2],v[v3],i),j),v[v4],k)-24)<eps)
                    add(r[v1],r[v2],r[v3],i+4,j+4,r[v4],k+4);
                if (e1&&fabs(f(v[v1],f(f(v[v2],v[v3],i),v[v4],j),k)-24)<eps)
                    add(r[v1],r[v2],r[v3],i+4,r[v4],j+4,k+4);
                if (e1&&e2&&fabs(f(v[v1],f(v[v2],f(v[v3],v[v4],i),j),k)-24)<eps)
                    add(r[v1],r[v2],r[v3],r[v4],i+4,j+4,k+4);
            }
}
int main(){
    for (int i=0;i<4;i++) scanf("%d",&v[i]);
    for (int i=0;i<4;i++)
        for (int j=0;j<4;j++) r[i]+=v[i]<v[j];
    check(0,1,2,3);
    check(0,1,3,2);
    check(0,2,1,3);
    check(0,2,3,1);
    check(0,3,1,2);
    check(0,3,2,1);
    check(1,0,2,3);
    check(1,0,3,2);
    check(1,2,0,3);
    check(1,2,3,0);
    check(1,3,0,2);
    check(1,3,2,0);
    check(2,0,1,3);
    check(2,0,3,1);
    check(2,1,0,3);
    check(2,1,3,0);
    check(2,3,0,1);
    check(2,3,1,0);
    check(3,0,1,2);
    check(3,0,2,1);
    check(3,1,0,2);
    check(3,1,2,0);
    check(3,2,0,1);
    check(3,2,1,0);
    sort(hs+1,hs+p+1);
    if (p) ans=1;
    for (int i=2;i<=p;i++) if (hs[i]!=hs[i-1]) ans++;
    printf("%d",ans);
}

C++11(clang++ 3.9) 解法, 执行用时: 3ms, 内存消耗: 376K, 提交时间: 2020-09-01 23:13:42

#include <bits/stdc++.h>
#define eps 1e-7 
using namespace std ;
int x[10010] ; 
int h,ans ;
int ra[10],a[10] ;
inline void add(int a1,int a2,int a3,int a4,int a5,int a6,int a7)
{  
    x[++h]=(a1|a2<<3|a3<<6|a4<<9|a5<<12|a6<<15|a7<<18);
    return;
}
double calc(double x,double y,int f)
{
	if (f==0) return x+y ;
	else if (f==1) return x-y ;
	else if (f==2) return x*y ;
	else return x/y ;
} 
inline bool find(int a,int b)
{
    if (a==0) return b>1;
    if (a==2) return b<2;
    return 1;
}
void check(int a1,int a2,int a3,int a4)
{
	for (int i=0;i<=3;i++)
	for (int j=0;j<=3;j++)
	for (int k=0;k<=3;k++)
	{
		bool f1=find(k,j),f2=find(j,i);
    	if (abs( calc ( calc ( calc (a[a1],a[a2],i) ,a[a3],j) ,a[a4],k) -24)<eps) 
        	add(ra[a1],ra[a2],i+4,ra[a3],j+4,ra[a4],k+4);
        if (f1 && abs(calc ( calc (a[a1],a[a2],i), calc (a[a3],a[a4],j),k)-24)<eps) 
        	add(ra[a1],ra[a2],i+4,ra[a3],ra[a4],j+4,k+4);	
        if (f1 && abs( calc (a[a1], calc ( calc (a[a2],a[a3],i),a[a4],j),k)-24)<eps) 
        	add(ra[a1],ra[a2],ra[a3],i+4,ra[a4],j+4,k+4);
        if (f2 && abs( calc ( calc (a[a1], calc (a[a2],a[a3],i),j),a[a4],k)-24)<eps) 
        	add(ra[a1],ra[a2],ra[a3],i+4,j+4,ra[a4],k+4);    
        if (f1 && f2 && abs( calc (a[a1], calc (a[a2], calc (a[a3],a[a4],i),j),k)-24)<eps) 
       	 	add(ra[a1],ra[a2],ra[a3],ra[a4],i+4,j+4,k+4);
	}
}
int main()
{
	for (int i=0;i<=3;i++) scanf("%d",&a[i]) ;
	for (int i=0;i<=3;i++)
	for (int j=0;j<=3;j++)
	if (a[i]<a[j]) ra[i]++ ;
	for (int i=0;i<=3;i++) 
	for (int j=0;j<=3;j++)
	for (int k=0;k<=3;k++)
	for (int l=0;l<=3;l++)
	if (i!=j && i!=k && i!=l && j!=k && j!=l && k!=l) 
	check(i,j,k,l) ; 
	sort(x+1,x+h+1) ;
	if (h) ans=1 ;
	for (int i=2;i<=h;i++) if (x[i]!=x[i-1]) ans++ ;
	printf("%d",ans) ;
} 

上一题