本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
【ICPC】2022合肥热身赛 B. Chess | 博弈论
题目
题目大意
Alice 和 Bob 玩游戏。
有一个 的棋盘摆满了棋子,输入描述了每个棋子是黑色还是白色。每次操作中:
- Alice 可以选择一个黑色棋子,并把该棋子它右边所有的棋子都取走。
- Bob 可以选择一个白色棋子,并把该棋子它右边所有的棋子都取走。
请对于给定的棋盘,判断该局游戏属于以下哪一种情况:
- Alice 必胜。
- Bob 必胜。
- 先手必胜。
- 后手必胜。
思路
显然每个人操作的最优策略都是:选择每一行最靠右的可以选择的棋子中,可以顺便带走最多对方可以选择的棋子的那一个。
因为数据范围很小,,我们可以分别让 Alice 和 Bob 作为先手,进行两次游戏,每次暴力模拟双方的选择。得到两次游戏的答案后:
- 如果不管谁是先手都是 Alice 胜利输出 1。
- 如果不管谁是先手都是 Bob 胜利输出 2。
- 两轮游戏均为先手获胜输出 3。
- 两轮游戏均为先手获胜输出 4。
代码
#include<bits/stdc++.h>
using namespace std;
int a[101][101],n,last[101];
int main() {
scanf("%d", &n);
int a1 = 0, b1 = 0, a2 = 0, b2 = 0;
for( int i = 1; i <= n; i++) {
string s;cin >> s;
for( int j = 1; j <= n; j++) {
if(s[j-1] == 'W') a[i][j] = 1;
}
} for( int i = 1; i <= n; i++) last[i] = n;
int alice = 1, bob = 0;
for( int ii = 1; ii <= 10000; ii++) {
pair<int,int>z;
int now = -1;
if(alice) {
for( int i = 1; i <= n; i++) {
int cnt0 = 0;
for( int j = last[i]; j >= 1; j--) {
if(a[i][j] == 1) {
if(cnt0 > now) {
now = cnt0;
z = {i, j-1};
}
break;
}
else cnt0++;
}
}
}
else {
for( int i = 1; i <= n; i++) {
int cnt0 = 0, cnt1 = 0;
for( int j = last[i]; j >= 1; j--) {
if(a[i][j] == 0) {
if(cnt1 > now) {
now = cnt1;
z = {i, j-1};
}
break;
}
else cnt1++;
}
}
}
if(now != -1) {
last[z.first] = z.second; alice ^= 1; bob ^= 1;
}
else {
if(alice) b1 = 1;
else a1 = 1;
break;
}
}
for( int i =1; i <= n; i++) last[i] = n;
bob = 1, alice = 0;
for( int ii = 1; ii <= 10000; ii++) {
pair<int,int>z;
int now = -1;
if(alice) {
for( int i = 1; i <= n; i++) {
int cnt0 = 0;
for( int j = last[i]; j >= 1; j--) {
if(a[i][j] == 1) {
if(cnt0 > now) {
now = cnt0;
z = {i, j-1};
}
break;
}
else cnt0++;
}
}
}
else {
for( int i = 1; i <= n; i++) {
int cnt0 = 0, cnt1 = 0;
for( int j = last[i]; j >= 1; j--) {
if(a[i][j] == 0) {
if(cnt1 > now) {
now = cnt1;
z = {i, j-1};
}
break;
}
else cnt1++;
}
}
}
if(now != -1) {
last[z.first] = z.second; alice ^= 1; bob ^= 1;
}
else {
if(alice) b2 = 1;
else a2 = 1;
break;
}
}
if(a1 && a2) printf("1\n");
else if(b1 && b2) printf("2\n");
else if(a1 && b1) printf("3\n");
else printf("4\n");
return 0;
}