P2361 yyy棋 题解
Sparrow_hmm · · 题解
题目描述:
P2361题目传送门
算法思路:
一道必胜策略好题。
应对方法:
须知:以下式子中
- 如果有中心点,己方先手,下中心点。
(通俗讲,如果长宽都是奇数,自己先手下
- 下对手中心对称的位置,举个
栗例子,如果对手下(x,y) ,我们就下在(A-x+1,B-y+1) 。
(通俗讲,粘着对手下!)
位置问题解决了,但是颜色该怎么办呢?
1. 考虑长宽都是奇数:
奇数不会出现
2. 考虑长或宽有偶数:
偶数会出现
(举个例子,
蒟蒻のAC代码
AC记录
#include <bits/stdc++.h>
using namespace std;
int a,b;
struct node
{
bool is_full=0;//有没有被下过
int color=-1;//什么颜色
bool can_be_1=1;//可以下黑棋
bool can_be_0=1;//可以下白棋
}f[10][10];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
void out()
{
cout<<"Buwanle";
exit(0);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>a>>b;
int t=0,flag=1;
if(a%2)t++;
if(b%2)t++;
//t作用是看长宽是否都是奇数
if(t==2)cout<<"First";
else
{
cout<<"Second";
flag=0;
}
cout<<'\n';
if(t==2)
{
//都是奇数的话先手,下中心点
cout<<a/2+1<<' '<<b/2+1<<' '<<1<<'\n';
for(int i=0;i<4;i++)
{
int tx=dx[i]+a/2+1;
int ty=dy[i]+b/2+1;
if(tx<1||ty<1||tx>a||ty>b)continue;
f[tx][ty].can_be_1=0;
}
}
int x,y,c;
while(cin>>x>>y>>c)
{
if(f[x][y].is_full)out();//已被下过
if(c==1&&f[x][y].can_be_1==0)out();//不可以下黑棋却下黑棋
if(c==0&&f[x][y].can_be_0==0)out();//不可以下白棋却下白棋
f[x][y].is_full=1;
f[x][y].color=c;
for(int i=0;i<4;i++)
{
int tx=dx[i]+x;
int ty=dy[i]+y;
if(tx<1||ty<1||tx>a||ty>b)continue;
if(c==1)f[tx][ty].can_be_1=0;
else f[tx][ty].can_be_0=0;
}//给上下左右附上不可以下同样颜色
int will_color=c;
if(!flag)
{
if(c==1)will_color=0;
else will_color=1;
}//看需要下什么颜色
int will_choose_x=a-x+1;
int will_choose_y=b-y+1;
//中心对称
cout<<will_choose_x<<' '<<will_choose_y<<' '<<will_color<<'\n';
//粘着对手下
for(int i=0;i<4;i++)
{
int tx=dx[i]+will_choose_x;
int ty=dy[i]+will_choose_y;
if(tx<1||ty<1||tx>a||ty>b)continue;
if(will_color==1)f[tx][ty].can_be_1=0;
else f[tx][ty].can_be_0=0;
}//给上下左右附上不可以下同样颜色
}
return 0;
}
总结:
遇事不决,小学数学!