CF1503B 3-Coloring
题面翻译
题目大意
本题是交互题。
Alice 和 Bob 在玩一个游戏:
初始有一个 \(n\times n\) 网格,我们用 \((i,j)\) 表示这个网格第 \(i\) 行第 \(j\) 列的位置,同时初始还有无限个颜色为 \(1,2,3\) 的三种代币。
接下来游戏会进行若干轮,每一轮 Alice 会选择一个颜色 \(a\),之后 Bob 需要选择一个颜色不是 \(a\) 的代币,并选择网格上一个没有放过代币的位置放上这个代币。
如果当完成一轮之后,有两个相邻的位置上放有相同颜色的代币,则 Alice 获胜。如果 \(n^2\) 轮之后 Alice 仍然没有获胜,则 Bob 获胜。
我们可以证明 Bob 有必胜策略,现在你需要扮演 Bob 并赢下游戏。
交互格式
首先交互器会给你一个整数 \(n\) 表示网格大小。接下来对于每一轮,你需要读入一个整数 \(a\) 表示你这一轮不可以选择什么颜色的代币,然后输出三个整数 \(b,i,j\) 表示你要在 \((i,j)\) 放上颜色为 \(b\) 的代币,\((i,j)\) 必须没有被放过代币。
如果你的操作不合法或是输掉了游戏,交互器会结束输入而你会得到 Wrong answer 的结果,如果 \(n^2\) 轮之后你还没有输掉游戏,请立即结束程序并得到 Accepted 的结果。
记得刷新缓冲区,交互器是自适应的。
\(2\leq n\leq100;1\leq a\leq3;\)
样例 #1
样例输入 #1
2
1
2
1
3
样例输出 #1
2 1 1
3 1 2
3 2 1
1 2 2
分析:
首先考虑如果只给两种颜色让你填,你会怎么办?
那必然是交叉地填,这样才能满足题目要求。
| 1 | 2 | 1 |
|---|---|---|
| 2 | 1 | 2 |
| 1 | 2 | 1 |
于是考虑把填颜色 \(1\) 的格子与填颜色 \(2\) 的格子都预处理出来,时间复杂度 \(O(n^2)\)
那么继续考虑题目给出的限制条件,禁止你使用一个颜色,那么你只需要填另一个颜色的格子即可。
但是如果一个颜色的格子全部都已经填完了怎么办?那么我们就可以使用颜色 \(3\) 来弥补,把颜色 \(3\) 填到本来被禁止的颜色的格子中即可。
考虑证明这种猜想:
由于不会出现颜色 \(1\) 与颜色 \(2\) 同时用完的情况,并且我们预处理出的格子中的任意颜色 \(1\) 的格子或任意颜色 \(2\) 的格子不会相邻,那么我们使用颜色 \(3\) 来替代了一种颜色之后,也不会出现相邻的情况。
总时间复杂度 \(O(n^2)\)
#include<bits/stdc++.h>
using namespace std;
int n,cl;
struct node{int x,y;};
stack<node>q1,q2;
int main(){
cin>>n;
for(int i=1;i<=n;i++){//预处理颜色1与颜色2的格子
for(int j=1;j<=n;j++){
if(i&1){
if(j&1)q1.push((node){i,j});
else q2.push((node){i,j});
}else{
if(j&1)q2.push((node){i,j});
else q1.push((node){i,j});
}
}
}
for(int i=1;i<=n*n;i++){
cin>>cl;
if(cl==1){//禁止颜色1
if(!q2.empty()){//颜色2的格子还有剩余
cout<<"2 "<<q2.top().x<<" "<<q2.top().y<<endl;
q2.pop();
}else{//否则拿颜色3代替
cout<<"3 "<<q1.top().x<<" "<<q1.top().y<<endl;
q1.pop();
}
}else if(cl==2){//禁止颜色2
if(!q1.empty()){//颜色1的格子还有剩余
cout<<"1 "<<q1.top().x<<" "<<q1.top().y<<endl;
q1.pop();
}else{//否则拿颜色3代替
cout<<"3 "<<q2.top().x<<" "<<q2.top().y<<endl;
q2.pop();
}
}else{//禁止颜色3,填颜色1或者颜色2都可以
if(!q1.empty()){
cout<<"1 "<<q1.top().x<<" "<<q1.top().y<<endl;
q1.pop();
}else{
cout<<"2 "<<q2.top().x<<" "<<q2.top().y<<endl;
q2.pop();
}
}
}
return 0;
}

浙公网安备 33010602011771号