[題解]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號