[题解]2025RaiCom(睿抗)CAIP省赛(本科) - 点格棋
RaiCom(睿抗)机器人开发者大赛CAIP-编程技能赛(RoboCom世界机器人开发者大赛),所有历史真题均在PTA平台教育超市售卖。
- 题源:RC-u3-点格棋
- 题意:给定\(N\times M\)的点阵,初始时所有点间均未连边,A和B轮流地在点阵上执行连边操作,A先手。对于每次连边,若相邻两点先前未连边,则每次操作可在其之间连接水平或竖直边,边长度为1。若有玩家连通了\(1\times 1\)大小的矩形,则添加最后边的玩家+1分,且其下回合继续操作。最终得分高的玩家获胜;若平局则B获胜。现给定\(S\)条格式为
当前玩家 起点横坐标 起点纵坐标 终点横坐标 终点纵坐标的游戏日志,需检查日志是否存在问题,有问题的日志为无效日志,跳过即可。日志编号从1开始。输出所有有问题的日志编号(若无则输出-1),最终的获胜者及其分数。 - 关键词:模拟(签到题)
- 题解:一道比较考验细节的大模拟。需要注意:
- 本回合实际玩家与应为玩家不符(尤其是连局情况)。设置变量
cur表示当前回合应为哪个玩家,并在回合结束后根据其是否成环决定是否轮换。 - 起点终点不能相同,且不能连斜边。判断曼哈顿距离是否为1即可。(二维平面上两点\((x_1,y_1)\)与\((x_2,y_2)\)的曼哈顿距离为\(|x_1-x_2|+|y_1-y_2|\))
- 起点和终点不能越界。设置check函数检查是否越界。
- 不能重复连边。存储到set里自动去重。
- 连边时需建成无向边。正向加边与反向加边。
- 一次连边可能形成2个环,分为起终点同行和起终点同列情况,以及起终点谁在上谁在下。对于起终点谁上谁下问题,只需固定一个方向上的点(即在上的)即可。
- 本回合实际玩家与应为玩家不符(尤其是连局情况)。设置变量
- 代码:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
using pp=pair<pair<int,int>,pair<int,int>>;
#define int ll
#define endl "\n"
int n,m,s;
bool check(int x,int y) {
return x>0&&x<=m&&y>0&&y<=n;
}
void solve(){
cin>>n>>m>>s;
vector<int>issue;
set<pp>ss;
int a=0,b=0;//a和b的得分
int cur=0;//本回合应为哪个玩家,A先手初始即为A
for(int i=1;i<=s;i++){
int p,sx,sy,ex,ey;cin>>p>>sx>>sy>>ex>>ey;
if(p!=cur){issue.push_back(i);continue;}//本回合实际玩家与应为玩家不符
if(abs(sx-ex)+abs(sy-ey)!=1){issue.push_back(i);continue;}//曼哈顿距离不为1
if(!check(sx,sy)||!check(ex,ey)){issue.push_back(i);continue;}//起终点越界
if(ss.count({{sx,sy},{ex,ey}})){issue.push_back(i);continue;}//重边
ss.insert({{sx,sy},{ex,ey}}),ss.insert({{ex,ey},{sx,sy}});//建无向边
int cnt=0;//本回合得分
if(sx==ex){//同列判环
int y_min=min(sy,ey);
if(sx>1&&ss.count({{sx,y_min},{sx-1,y_min}})&&ss.count({{sx-1,y_min},{sx-1,y_min+1}})&&ss.count({{sx,y_min+1},{sx-1,y_min+1}}))cnt++;
if(sx<m&&ss.count({{sx,y_min},{sx+1,y_min}})&&ss.count({{sx+1,y_min},{sx+1,y_min+1}})&&ss.count({{sx,y_min+1},{sx+1,y_min+1}}))cnt++;
}
else if(sy==ey){//同行判环
int x_min=min(sx,ex);
if(sy>1&&ss.count({{x_min,sy},{x_min,sy-1}})&&ss.count({{x_min,sy-1},{x_min+1,sy-1}})&&ss.count({{x_min+1,sy},{x_min+1,sy-1}}))cnt++;
if(sy<n&&ss.count({{x_min,sy},{x_min,sy+1}})&&ss.count({{x_min,sy+1},{x_min+1,sy+1}})&&ss.count({{x_min+1,sy},{x_min+1,sy+1}}))cnt++;
}
if(cnt){//得分,下回合玩家不变
(p==0)?(a+=cnt):(b+=cnt);
cur=p;
}else cur=p^1;//未得分,下回合轮换玩家
}
if(issue.size()){
for(int i=0;i<issue.size();i++){
cout<<issue[i];
if(i!=issue.size()-1) cout<<' ';//sb PTA,行末空格自己不能吃
}
cout<<endl;
}else cout<<-1<<endl;
(a>b)?cout<<0<<' '<<a<<endl:cout<<1<<' '<<b<<endl;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
int t=1;
while(t--) solve();
return 0;
}

浙公网安备 33010602011771号