A.Start
洛谷原题链接
一道大模拟,赛时20pts。
教授の高光时刻
- 输出没加句号、空格。 - C++向0取整。 - DOUBLE没传递。 - -9操作成-1(复制粘贴导致的)。 - 负数位运算卡常。其实这题还是比较简单的,细节在题目中讲的很详细,跟着它说的去做就好了。我的方法是把每个玩家用一个结构体表示出来,把牌们用变量储存起来,变量名对应牌的类型,变量值对应该种牌的数目。摸牌对应 \(got\) 函数,出牌对应 \(use\) 函数。有无 \(DOUBLE\) 效果对应两种选牌策略,尽可能大对应 \(high\) 函数,尽可能小对应 \(low\) 函数。为了方便,我把以上几个函数也都放到了结构体里。本题思路不难,但考验码力,所以请看代码注释。
#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;
}
标签:return,++,CSP,add,&&,mx,rn,考试题,集训
From: https://www.cnblogs.com/ywhhdjser-97/p/18310194