题解:P15081 [ICPC 2024 Chengdu R] Grand Prix of Ballance
P15081题解
题意简述
有
第一种,表示一个关卡开启。
第二种,表示一位选手完成了某关卡。
第三种,表示一位选手放弃了某关卡。
但玩家只能完成或放弃当前正在进行的关卡,关卡不能重复开启,当一位玩家完成或放弃了某关卡后,该玩家针对该关卡的后续所有消息都将被忽略。
求每位参与者的总积分,降序输出。
解题思路
理解题意之后直接模拟,造一个玩家结构体,存放该玩家的编号、总积分、当前关卡的状态(未知、完成、或者放弃)。
按照题意处理每个描述,注意特判。
最后排序输出即可~。
(多测不清空见祖宗)
还不明白?看代码!
代码实现
#include<bits/stdc++.h>
#define int long long
using namespace std;
int T,m,q,n;
int id,x;
struct nnd{
int jf,id,zt;//积分、id、当前关卡状态:0未知,nw完成,-nw放弃(nw为当前关卡编号)
}a[100010];
bool cmp(nnd x,nnd y){
return x.jf==y.jf?(x.id<y.id):(x.jf>y.jf);//积分作为第一关键字,编号作为第二关键字
}
signed main(){
scanf("%lld",&T);
while(T--){
scanf("%lld %lld %lld",&n,&m,&q);//读入
for(int i=1;i<=m;i++) a[i].id=i,a[i].jf=a[i].zt=0;//每位玩家的id重新记下,积分和当前关卡状态清零
int nw=0,t=0;//当前关卡、通过人数(初始值为0)
for(int i=1;i<=q;i++){
int op,id,x;
scanf("%lld",&op);
if(op==1){
if(nw>n) continue;//判断是否当前关卡都不在n关的范围内了,是则跳过
scanf("%lld",&nw),t=0;
}
else if(op==2){
scanf("%lld %lld",&id,&x);
if(x!=nw||abs(a[id].zt)==nw)//当前关不在n关范围内或该玩家已经有了相应状态(完成或放弃)
continue;//直接跳过
a[id].zt=nw;//状态赋值为nw,表示已经完成
a[id].jf+=(m-t++);//积分累计,完成人数加一
}
else if(op==3){
scanf("%lld %lld",&id,&x);
if(x!=nw||abs(a[id].zt)==nw) continue;//特判同上
a[id].zt=-nw;//状态赋值为-nw,表示放弃该关卡
}
}
sort(a+1,a+m+1,cmp);//排序
for(int i=1;i<=m;i++) printf("%lld %lld\n",a[i].id,a[i].jf);//输出
}
return (0^0);//卖个萌(
}
你学会了吗。