Codeforces Round #712 (Div. 1) B. 3-Coloring
Codeforces Round #712 (Div. 2) D. 3-Coloring
题意
在一个 n ∗ n n*n n∗n的网格中做游戏,使用 3 3 3种颜色对每个网格涂色
每回合系统会给出一种禁止的颜色 a a a
你必须选择一个网格,使用除 a a a以外的两种颜色任意一种对其进行涂色
需要保证没有相邻的网格颜色是相同的
做完这 n ∗ n n*n n∗n回合游戏以获得胜利
限制
I n p u t : 2 ≤ n ≤ 100 1 ≤ a ≤ 3 O u t p u t : 1 ≤ b ≤ 3 , a ≠ b , 1 ≤ i , j ≤ n \begin{aligned} Input:&\\ &2\le n\le 100\\ &1\le a\le 3\\ Output:&\\ &1\le b\le 3,\ a\neq b,\ 1\le i,j\le n \end{aligned} Input:Output:2≤n≤1001≤a≤31≤b≤3, a=b, 1≤i,j≤n
思路
可以发现,刚开始我们始终可以使用三种颜色的两种来间隔填满整个网格,如下图所示
故可以先确定 ( 1 , 1 ) (1,1) (1,1)与 ( 1 , 2 ) (1,2) (1,2)两点的颜色(不同)
对于上图,这代表着所有绿色的位置颜色都应与 ( 1 , 1 ) (1,1) (1,1)的颜色相同,所有蓝色的位置颜色都应与 ( 1 , 2 ) (1,2) (1,2)的颜色相同
在任意一种颜色网格未填满时,不论系统该回合禁止使用哪种颜色,都存在涂色的方案
而一旦某种颜色的网格被涂满(如下图中所有蓝色底的网格被涂满了)
此时明显就能发现,剩下的所有网格都能使用除了蓝色底网格使用的颜色外的两种颜色的任意一种填入
代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
int n,x,y,p1,p2;
vector<P> v1,v2;
int f(int a){
return (a==1?2:1);
}
int f(int a,int b){ //f函数返回与传入颜色不同的任意一种颜色
if(a==b)
return f(a);
if(a>b)
swap(a,b);
if(a==1&&b==2)
return 3;
if(a==1&&b==3)
return 2;
return 1;
}
void solve(int a)
{
if(p1==v1.size()) //如果v1表示的网格都被用完
{
printf("%d %d %d\n",f(a,x),v2[p2].first,v2[p2].second);
p2++; //那么剩余的所有网格只要不是被禁止的颜色a以及v1表示的颜色x,都能作为方案,下同
}
else if(p2==v2.size())
{
printf("%d %d %d\n",f(a,y),v1[p1].first,v1[p1].second);
p1++;
}
else
{
if(a==x) //如果被禁止的颜色与此时v1内表示的网格颜色相同
{
printf("%d %d %d\n",y,v2[p2].first,v2[p2].second);
p2++; //那就将v2表示的网格进行涂色,下同
}
else
{
printf("%d %d %d\n",x,v1[p1].first,v1[p1].second);
p1++;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if((i+j)&1) //根据i+j的奇偶性分组
v2.push_back(P(i,j));
else
v1.push_back(P(i,j));
}
p1=p2=1; //下面使用了(1,1)与(1,2)两点,故p1 p2从1开始
int a;
scanf("%d",&a);
x=f(a);
printf("%d 1 1\n",x);
fflush(stdout);
scanf("%d",&a);
y=f(a,x);
printf("%d 1 2\n",y);
fflush(stdout);
int t=n*n-2;
while(t--)
{
scanf("%d",&a);
solve(a);
fflush(stdout);
}
return 0;
}