RC-u3 骰子游戏

睿抗2023本科组第三题

#include<bits/stdc++.h>
using namespace std;
//声明全局变量
int n,k[6],level1,level2,t[6],f[32],r[32];
//函数get_level:根据五个骰子的点数,返回当前获胜等级
int get_level(int s[]){
    //首先对骰子点数进行排序,以便后续判断
    sort(s+1,s+1+5);
    //下面的条件判断对应于题目中给出的获胜等级判断逻辑
    //注意数组是从1开始索引的,符合输入习惯
    if(s[1]==s[2]&&s[2]==s[3]&&s[3]==s[4]&&s[4]==s[5])
    return 9;//五个同点数
    if(s[1]==s[2]&&s[2]==s[3]&&s[3]==s[4]||s[2]==s[3]&&s[3]==s[4]&&s[4]==s[5])
    return 8;//四个同点数
    if(s[1]==s[2]&&s[2]!=s[3]&&s[3]==s[4]&&s[4]==s[5]||s[1]==s[2]&&s[2]==s[3]&&s[3]!=s[4]&&s[4]==s[5])
    return 7;//葫芦
    if(s[1]==2&&s[2]==3&&s[3]==4&&s[4]==5&&s[6]==6)
    return 6;//六高顺子
    if(s[1]==1&&s[2]==2&&s[3]==3&&s[4]==4&&s[5]==5)
    return 5;//五高顺子
    if(s[1]==s[2]&&s[2]==s[3]||s[2]&&s[2]==s[3]&&s[3]==s[4]||s[3]==s[4]&&s[4]==s[5])
    return 4;//三个同点数
    if(s[1]==s[2]&&s[3]==s[4]||s[1]==s[2]&&s[4]==s[5]||s[2]==s[3]&&s[4]==s[5])
    return 3;//两对
    for(int i=2;i<=5;i++)
        if(s[i]==s[i-1])
        return 2;
    return 1;//无
}
//函数get_1:计算一个整数的二进制表示中1的个数
int get_1(int a){
    int sum=0;
    while(a){
        if(a%2==1) sum++;
        a/=2;
    }
    return sum;
}
int main(){
    cin>>n;
    while(n--){
        for(int i=1;i<=5;i++)
            cin>>k[i];
            //获取初始获胜等级
            level1=get_level(k);
            //初始化数组f和r
            memset(f,0,sizeof(f));
            memset(r,0,sizeof(r));
            //初始化变量结果
            int res=0;
            int zi=0;
            int mu=1;
            double gv=-1;
            //遍历所有可能的骰子点数组合
            for(int a=1;a<=6;a++){
                for(int b=1;b<=6;b++){
                    for(int c=1;c<=6;c++){
                        for(int d=1;d<=6;d++){
                            for(int e=1;e<=6;e++){
                                //计算每种点数组合
                                t[1]=a,t[2]=b,t[3]=c,t[4]=d,t[5]=e;
                                int count=0;
                                //标记与原点数不同的骰子位置
                                for(int i=1;i<=5;i++){
                                    if(k[i]!=t[i]) count|=1<<(i-1);
                                }
                                //计算所有包含该点数变化的组合,并更新频次和成功机会
                                for(int i=1;i<=31;i++){
                                    if((i&count)==count){
                                        f[i]++;
                                        level2=get_level(t);
                                        if(level2>level1){
                                            r[i]++;
                                        }
                                    }
                                }
                            }
                           
                        }
                    }
                }
            }
                 //寻找使得获胜等级提高的最佳操作方案
            for(int i=1;i<=31;i++){
            if(r[i]==0) continue;
            double g=(double)r[i]/f[i];
            int c=get_1(i);
            //如果发现更好的操作方案,则更新结果变量
            if(g>gv||(g==gv&&c<res)){
            gv=g,res=c,zi=r[i],mu=f[i];
        }
    }
        //简化结果分数
    if(zi>0&&mu>0){
    int z=__gcd(zi,mu);
    zi/=z;
    mu/=z;
}
//输出结果
printf("%d %d %d\n",res,zi,mu);
        }
return 0;
}

可得记住咯————

原网址

posted @ 2024-05-31 20:35  pengfu_xin  阅读(216)  评论(0编辑  收藏  举报