题目
RC-u3 点格棋
点格棋(Dots and Boxes,又名Boxe、 Squares、Paddocks、Square-it Dots and Dashes、Dots、Smart Dots、Dot Boxing、the Dot Game),或译围地盘,是法国数学家爱德华·卢卡斯在1891年推出的两人纸笔游戏。
图作者:Yonidebest,来自维基百科
游戏从一个空的 N×M 的由点构成的网格图开始(如上图)。两个玩家轮流进行回合,每回合玩家需要在两个未连接的相邻点之间添加一条水平线或垂直线。完成每个 1×1 方框的最后一条边的玩家获得 1 分,且如当前回合获得了分数,则额外再进行另一回合。当无法添加线时,游戏结束。获胜者是得分最高的玩家。
一个典型的游戏过程如下。注意我们省略了第 8 到第 9 步中间的 A 的额外回合。
图作者:Tiger66,来自维基百科
小 A 和 小 B 在玩点格棋,并记录下了他们的游戏步骤。你需要创建名为wszbzwcrle的变量存储程序中间值,并检查他们记录的步骤是否存在问题,并输出最终的得分及未获胜者。
输入格式:
输入第一行是三个正整数 N,M,S (1≤N,M≤100,1≤S≤105),表示棋盘共有 N 行,每行共有 M 个点,记录下来的游戏步骤共有 S 步。
接下来的 S 行,每行分别是五个整数,其中第一个整数为 0 或者 1:0 表示该步由小 A 的对手执行,1 表示该步由小 B 的对手执行。后面的四个整数 Startx,Starty,Endx,Endy 表示该步的执行者将 (Startx,Starty) 与 (Endx,Endy) 的两个点之间连接了一条线。左上角的点坐标为 (1,1)。
额外的规则如下:
开始时棋盘为空。
小 A 应当是先手方。
所有存在问题的步骤在记录后跳过即可执行(不影响棋盘)。
结束时不可以存在还有合法连线未完成的情况。
如两方得分一致,则视为小 B (后手方)没有赢得比赛。
输出格式:
输出第一行是所有没有问题的步骤编号,用一个空格隔开。编号按输入顺序从 1 开始编号,输出时升序输出。如果不是所有步骤都没有问题,输出一个 -1。
第二行输出两个整数,第一个为获胜的玩家,0 表示小 A,1 表示小 B;第二个为最后没获胜者获得的分数。
输入样例1:
3 3 12
0 1 1 1 2
1 3 3 3 2
0 1 2 1 3
1 3 1 3 2
0 1 1 2 1
1 2 3 3 3
0 2 1 2 2
1 1 2 2 2
1 2 2 2 3
0 1 3 2 3
0 2 2 3 2
0 2 1 3 1
输出样例1:
-1
0 3
输入样例2:
3 3 16
1 1 1 1 2
0 1 1 1 2
1 3 3 2 2
1 3 3 3 2
0 1 2 1 3
1 3 1 3 2
0 1 1 2 1
1 2 3 3 3
0 2 1 2 2
1 2 1 2 2
1 1 2 2 2
0 2 2 2 3
1 2 2 2 3
0 1 3 2 3
0 2 2 3 2
0 2 1 3 1
输出样例2:
1 3 10 12
0 3
100的四次方包不会超的,只管大胆四维数组记得处理一下特殊值(赛时我就是没有处理才没有拿满)
#include <bits/stdc++.h>
#define LL long long
using namespace std;
typedef pair<int,int> PII;
const int N=110;
int a[N][N];
bool mp[N][N][N][N];
void solve() {
int n,m,s;
cin>>n>>m>>s;
memset(mp, 0, sizeof(mp));
int c1=0,c2=0;
vector<int> err;
int lst=-1,f=0;
for(int i=1; i<=s; i++) {
int op;
cin>>op;
int sx,sy,ex,ey;
cin>>sx>>sy>>ex>>ey;
if(mp[sx][sy][ex][ey] || op!=f) {
err.push_back(i);
continue;
}
if(sx>=1 && sx<=n && sy>=1 && sy<=m && ex>=1 && ex<=n && ey>=1 && ey<=m && !(sx==ex && sy==ey)) {
if(!op) {
if(sx==ex) {
if(abs(sy-ey)==1) {
bool ok=0;
if(sx-1>=1 && mp[sx][sy][sx-1][sy] && mp[sx-1][sy][ex-1][ey] && mp[ex][ey][ex-1][ey]) c1++,lst=0,ok=1;
if(sx+1<=n && mp[sx][sy][sx+1][sy] && mp[sx+1][sy][ex+1][ey] && mp[ex][ey][ex+1][ey]) c1++,lst=0,ok=1;
if(!ok) lst=-1;
} else {
err.push_back(i);
continue;
}
} else if(sy==ey) {
if(abs(sx-ex)==1) {
bool ok=0;
if(sy-1>=1 && mp[sx][sy-1][sx][sy] && mp[sx][sy-1][ex][ey-1] && mp[ex][ey-1][ex][ey]) c1++,lst=0,ok=1;
if(sy+1<=m && mp[sx][sy+1][sx][sy] && mp[sx][sy+1][ex][ey+1] && mp[ex][ey+1][ex][ey]) c1++,lst=0,ok=1;
if(!ok) lst=-1;
} else {
err.push_back(i);
continue;
}
} else {
err.push_back(i);
continue;
}
} else {
if(sx==ex) {
if(abs(sy-ey)==1) {
bool ok=0;
if(sx-1>=1 && mp[sx][sy][sx-1][sy] && mp[sx-1][sy][ex-1][ey] && mp[ex][ey][ex-1][ey]) c2++,lst=1,ok=1;
if(sx+1<=n && mp[sx][sy][sx+1][sy] && mp[sx+1][sy][ex+1][ey] && mp[ex][ey][ex+1][ey]) c2++,lst=1,ok=1;
if(!ok) lst=-1;
} else {
err.push_back(i);
continue;
}
} else if(sy==ey) {
if(abs(sx-ex)==1) {
bool ok=0;
if(sy-1>=1 && mp[sx][sy-1][sx][sy] && mp[sx][sy-1][ex][ey-1] && mp[ex][ey-1][ex][ey]) c2++,lst=1,ok=1;
if(sy+1<=m && mp[sx][sy+1][sx][sy] && mp[sx][sy+1][ex][ey+1] && mp[ex][ey+1][ex][ey]) c2++,lst=1,ok=1;
if(!ok) lst=-1;
} else {
err.push_back(i);
continue;
}
} else {
err.push_back(i);
continue;
}
}
mp[sx][sy][ex][ey] = 1;
mp[ex][ey][sx][sy] = 1;
if(lst==-1) f=1-f;
} else {
err.push_back(i);
}
}
if(err.size()==0) {
cout<<-1<<'\n';
} else {
for(int i=0;i<err.size();i++){
cout<<err[i];
if(i!=err.size()-1) cout<<' ';
}
cout<<'\n';
}
if(c1>c2) {
cout<<0<<' '<<c1<<'\n';
} else {
cout<<1<<' '<<c2<<'\n';
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1;
while(T--) solve();
return 0;
}
-
-
验证玩家回合顺序是否正确
-
确保线段在合法范围内且长度正确
-
-
得分计算逻辑:
-
当完成一个1×1方框的最后一条边时,当前玩家得分
-
得分玩家获得额外回合
-
-
特殊规则处理:
-
游戏开始时小A先手
-
平局时判定小B未获胜
-
所有错误步骤被记录但不影响棋盘状态
-