暑假集训CSP提高模拟1考试题解
A.Start
洛谷原题链接
一道大模拟,赛时20pts。
教授の高光时刻
- 输出没加句号、空格。 - C++向0取整。 - DOUBLE没传递。 - -9操作成-1(复制粘贴导致的)。 - 负数位运算卡常。其实这题还是比较简单的,细节在题目中讲的很详细,跟着它说的去做就好了。我的方法是把每个玩家用一个结构体表示出来,把牌们用变量储存起来,变量名对应牌的类型,变量值对应该种牌的数目。摸牌对应
#include<bits/stdc++.h> using namespace std; int a,b,c,bn,p,trn,dou;//bn表示起始玩家,p存值,trn存循环方向,dou存DOUBLE效果 struct node { string name;//名字 int pass,turn,doubla,up,dn;//前三个对应三种解牌,up对应乘法牌,dn对应除法牌 int add[11],del[11],ctrl[11];//add对应7种加法牌,del对应3种减法牌,ctrl对应三种固定牌 inline void got(string y)//得到y牌 { if(y=="A1") { add[1]++; return; } if(y=="A2") { add[2]++; return; } if(y=="A5") { add[3]++; return; } if(y=="A9") { add[4]++; return; } if(y=="A19") { add[5]++; return; } if(y=="A49") { add[6]++; return; } if(y=="A99") { add[7]++; return; } if(y=="B1") { del[1]++; return; } if(y=="B9") { del[2]++; return; } if(y=="B19") { del[3]++; return; } if(y=="C2") { up++; return; } if(y=="D2") { dn++; return; } if(y=="E0") { ctrl[1]++; return; } if(y=="E49") { ctrl[2]++; return; } if(y=="E99") { ctrl[3]++; return; } if(y=="PASS") { pass++; return; } if(y=="TURN") { turn++; return; } if(y=="DOUBLE") { doubla++; return; } } inline void use(string y)//注意此处是先找到应出的牌再进行后续操作 { if(y=="A1") { add[1]--; p+=1; return; } if(y=="A2") { add[2]--; p+=2; return; } if(y=="A5") { add[3]--; p+=5; return; } if(y=="A9") { add[4]--; p+=9; return; } if(y=="A19") { add[5]--; p+=19; return; } if(y=="A49") { add[6]--; p+=49; return; } if(y=="A99") { add[7]--; p+=99; return; } if(y=="B1") { del[1]--; p-=1; return; } if(y=="B9") { del[2]--; p-=9; return; } if(y=="B19") { del[3]--; p-=19; return; } if(y=="C2") { up--; p*=2; return; } if(y=="D2") { dn--; if(p<0&&p%2!=0)//手写向下取整 { p/=2; p-=1; } else { p/=2; } return; } if(y=="E0") { ctrl[1]--; p=0; return; } if(y=="E49") { ctrl[2]--; p=49; return; } if(y=="E99") { ctrl[3]--; p=99; return; } if(y=="PASS") { pass--; return; } if(y=="TURN") { turn--; trn^=1; return; } if(y=="DOUBLE") { doubla--; dou=1; return; } } inline string high()//high和low一定要注意判断的顺序 { int mx=-0x3f3f3f3f; string rn="LOST";//初始化 if(p*2<=99&&up>0) { mx=p*2; rn="C2"; } if(p+99<=99&&p+99>mx&&add[7]>0) { mx=p+99; rn="A99"; } if(p+49<=99&&p+49>mx&&add[6]>0) { mx=p+49; rn="A49"; } if(p+19<=99&&p+19>mx&&add[5]>0) { mx=p+19; rn="A19"; } if(p+9<=99&&p+9>mx&&add[4]>0) { mx=p+9; rn="A9"; } if(p+5<=99&&p+5>mx&&add[3]>0) { mx=p+5; rn="A5"; } if(p+2<=99&&p+2>mx&&add[2]>0) { mx=p+2; rn="A2"; } if(p+1<=99&&p+1>mx&&add[1]>0) { mx=p+1; rn="A1"; } if(p-1<=99&&p-1>mx&&del[1]>0) { mx=p-1; rn="B1"; } if(p-9<=99&&p-9>mx&&del[2]>0) { mx=p-9; rn="B9"; } if(p-19<=99&&p-19>mx&&del[3]>0) { mx=p-19; rn="B19"; } int qwer; if(p<0&&p%2!=0) { qwer=p/2; qwer--; } else { qwer=p/2; } if(qwer<=99&&qwer>mx&&dn>0) { mx=qwer; rn="D2"; } if(99>mx&&ctrl[3]>0) { mx=99; rn="E99"; } if(49>mx&&ctrl[2]>0) { mx=49; rn="E49"; } if(0>mx&&ctrl[1]>0) { mx=0; rn="E0"; } if(rn=="LOST"&&pass>0) { return "PASS"; } if(rn=="LOST"&&turn>0) { return "TURN"; } if(rn=="LOST"&&doubla>0) { return "DOUBLE"; } return rn; } inline string low() { int mn=0x3f3f3f3f; string rn="LOST"; if(rn=="LOST"&&pass>0) { return "PASS"; } if(rn=="LOST"&&turn>0) { return "TURN"; } if(rn=="LOST"&&doubla>0) { return "DOUBLE"; } int qwer; if(p<0&&p%2!=0) { qwer=p/2; qwer--; } else { qwer=p/2; } if(qwer<=99&&dn>0) { mn=qwer; rn="D2"; } if(p-19<=99&&p-19<mn&&del[3]>0) { mn=p-19; rn="B19"; } if(p-9<=99&&p-9<mn&&del[2]>0) { mn=p-9; rn="B9"; } if(p-1<=99&&p-1<mn&&del[1]>0) { mn=p-1; rn="B1"; } if(p+1<=99&&p+1<mn&&add[1]>0) { mn=p+1; rn="A1"; } if(p+2<=99&&p+2<mn&&add[2]>0) { mn=p+2; rn="A2"; } if(p+5<=99&&p+5<mn&&add[3]>0) { mn=p+5; rn="A5"; } if(p+9<=99&&p+9<mn&&add[4]>0) { mn=p+9; rn="A9"; } if(p+19<=99&&p+19<mn&&add[5]>0) { mn=p+19; rn="A19"; } if(p+49<=99&&p+49<mn&&add[6]>0) { mn=p+49; rn="A49"; } if(p+99<=99&&p+99<mn&&add[7]>0) { mn=p+99; rn="A99"; } if(p*2<=99&&p*2<mn&&up>0) { mn=p*2; rn="C2"; } if(0<mn&&ctrl[1]>0) { mn=0; rn="E0"; } if(49<mn&&ctrl[2]>0) { mn=49; rn="E49"; } if(99<mn&&ctrl[3]>0) { mn=99; rn="E99"; } return rn; } inline void clear()//已经输了,弃置所有牌 { add[1]=0; add[2]=0; add[3]=0; add[4]=0; add[5]=0; add[6]=0; add[7]=0; del[1]=0; del[2]=0; del[3]=0; ctrl[1]=0; ctrl[2]=0; ctrl[3]=0; up=0; dn=0; pass=0; turn=0; doubla=0; return; } }player[11]; queue<string>card;//队列实现牌堆 string in; inline void play(int x)//模拟一局游戏,内部注意输出内容的细节,如空格和标点 { printf("Round %d:\n",x); trn=0,dou=0,p=0; int pl=bn;//pl存当前位置 while(1) { string out; if(dou)//DOUBLE buff { out=player[pl].low(); if(out=="LOST") { cout<<player[pl].name<<" lost the game."<<'\n'; bn=pl; return; } player[pl].use(out); cout<<player[pl].name<<" used "<<out<<",now p="<<p<<".\n"; dou=0; player[pl].got(card.front()); card.pop(); if(out=="PASS"||out=="TURN"||out=="DOUBLE")//直接转移,且传递DOUBLE buff { if(trn) { pl--; if(pl<1) { pl=a; } } else { pl++; if(pl>a) { pl=1; } } dou=1; } continue; } out=player[pl].high(); if(out=="LOST") { cout<<player[pl].name<<" lost the game."<<'\n'; bn=pl; return;//结束游戏 } player[pl].use(out); cout<<player[pl].name<<" used "<<out<<",now p="<<p<<".\n"; player[pl].got(card.front()); card.pop(); if(trn)//往前走 { pl--; if(pl<1) { pl=a; } } else { pl++; if(pl>a) { pl=1; } } } } int main() { scanf("%d%d%d",&a,&b,&c); bn=1; for(int i=1;i<=a;i++) { cin>>player[i].name; for(int j=1;j<=3;j++) { cin>>in; player[i].got(in); } } for(int i=1;i<=c;i++) { cin>>in; card.push(in); } for(int i=1;i<=b;i++) { play(i); player[bn].clear();//此时的bn是失败者 for(int j=1;j<=3;j++)//重新摸牌 { in=card.front(); card.pop(); player[bn].got(in); } } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】