棋(chess)
【题目描述】
这是一个很有意思的益智类小游戏。
初始有一个19×1919×19的空棋盘。
有两个玩家(我们简称他们为小D和小L),两个人轮流进行操作,小D先手。
轮到小D的时候他会将一个空格子染黑而小L则会将一个空格子染白。
定义两个格子联通为两个格子相邻的边有一个相同。
定义联通块就是相同颜色且联通的两个格子连接后的联通块。
定义一个联通块的气为不在该联通块中且存在一个与其联通的在联通块的格子中空格子的数量。
现在我们考虑小D或小L的一次操作,如果将一个有颜色的格子染色则不合法。
当我们落下一颗子后。
首先,我们考虑在落下棋子后,考虑所有不包含该棋子的联通块,如果该联通块气为零,则该联通块包含的所有棋子消失,这个操作被称为提子。
如果在执行完上述操作后,落下棋子所在联通块的气为零。 则该落子不合法。
其中有一种特殊情况,当你一颗合法落子消除掉对方恰好一颗棋子时,对方下一步如果只恰好消除你上次落下的那一颗棋子,则对方的该落子不合法,这种情况被称为劫。
【输入格式】
从文件chess.in
中读取数据
第一行输入一个数nn,表示尝试下棋次数。
接下来nn行,每行两个数xx,yy。
表示在(x,y)(x,y)落子。
如果该落子合法,则进行落子及提子,下次对方落子。
如果不合法,则不进行落子及提子,下次己方继续落子。
【输出格式】
输出到文件chess.out
中
对于第ii次尝试落子。
如果第ii次尝试落子不合法,只输出一行invalid
。
否则先输出一行valid
,接着输出一个19×1919×19的矩阵,表示执行完该操作后棋盘的情况(1
表示黑子,2
表示白子,0
表示空)
具体输出方式见样例。
【数据范围与约定】
- n≤104n≤104 1≤x,y≤191≤x,y≤19
子任务 11:只有一组数据,输入给定,见下发文件chess1.in
。分值:1010
子任务 22:只有一组数据,输入给定,见下发文件chess2.in
。分值:1010
子任务 33:不存在劫的情况。分值:3030
子任务 44:无。分值:5050
样例见下发文件simple1.in
simple1.out
。(注无文件读写)
AC代码:
#include<bits/stdc++.h>//T3
#define ll long long
#define g(a,b) __gcd(a,b)
#define F1(a,n,b) for(int a = 1;a <= n;a += b)
#define F2(a,b,n,c) for(int a = b;a <= n;a += c)
#define l2(a) log(a) / log(2)
#define pll pair<ll,ll>
#define ull unsigned long long
#define pii pair<int,int>
#define pq1 priority_queue<int>
#define pq2 priority_queue<int,vector<int>,greater<int>>
#define ui unsigned int
using namespace std;
ll n;
ll dx[] = {0,1,-1,0,0},dy[] = {0,0,0,1,-1};
ll f[25][25],pre[25][25];
bool vis[25][25],v[25][25];
void dfs(ll x,ll y){
if(vis[x][y])return;
vis[x][y] = 1;
for(int i = 1;i <= 4;++i){
ll fx = x + dx[i],fy = y + dy[i];
if(f[fx][fy] != f[x][y])continue;
dfs(fx,fy);
}
return;
}
ll ask(ll x,ll y){
memset(vis,0,sizeof(vis));
dfs(x,y);
ll q = 0;
for(int i = 1;i <= 19;++i){
for(int j = 1;j <= 19;++j){
if(vis[i][j]){
v[i][j] = 1;
continue;
}
if(f[i][j])continue;
bool flag = 0;
for(int k = 1;k <= 4;++k){
ll fx = i + dx[k],fy = j + dy[k];
if(vis[fx][fy])flag = 1;
}
if(flag)q++;
}
}
return q;
}
signed main(){
cin>>n;
ll x,y,px,py,tr = 1;
px = py = 0;
while(n--){
cin>>x>>y;
if(f[x][y]){
puts("invalid");
continue;
}
memcpy(pre,f,sizeof(pre));
memset(v,0,sizeof(v));
f[x][y] = tr;
ll g,ax,ay;
g = ax = ay = 0;
for(int i = 1;i <= 19;++i){
for(int j = 1;j <= 19;++j){
if(!f[i][j])continue;
if(f[i][j] == f[x][y])continue;
if(v[i][j])continue;
ll q = ask(i,j);
if(!q){
for(int u = 1;u <= 19;++u){
for(int uu = 1;uu <= 19;++uu){
if(vis[u][uu]){
g++;
ax = u;
ay = uu;
f[u][uu] = 0;
}
}
}
}
}
}
ll q = ask(x,y);
if(!q||(g == 1&&px == ax&&py == ay)){
memcpy(f,pre,sizeof(f));
puts("invalid");
continue;
}
if(g == 1){
px = x;
py = y;
}
else {
px = py = 0;
}
puts("valid");
for(int i = 1;i <= 19;++i){
for(int j = 1;j <= 19;++j){
cout<<f[i][j]<<" ";
}
puts("");
}
tr = ((tr - 1) ^ 1) + 1;
}
}
/*
*/