2013杭州区域赛的题目
题意:
模拟围棋,看最后黑白棋子各剩多少。需要注意的是,这题能下一个棋子把自己的棋子都堵死,然后消掉(现实中没人会这么下吧。。。)。
思路:
1.用map<pair<int,int>,int> 模拟二维数组。
2.用并查集维护连通块。
3.对每个连通块再维护一个set,保存连通块的气(一个棋子在棋盘上,与它直线紧邻的空点是这个棋子的“气”)
然后,并查集合并的时候,set从小的合并到大的。如果set.size()==0 说明连通快要被消掉。再注意一些细节就可以了。
code:
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;
#define N 10010
#define ll long long
#define ALL(x) x.begin(),x.end()
#define CLR(x,a) memset(x,a,sizeof(x))
typedef pair<int,int> PI;
const int INF=0x3fffffff;
const int MOD =1000000007;
const double EPS=1e-7;
const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};
set<PI> space[N];
map<PI,int> mp,id;
class DisjointSet{
public:
int par[N];
void init(int n){
for(int i=0;i<n;i++) par[i]=i;
}
int find(int x){
return (x==par[x])? x : (par[x]=find(par[x]));
}
void merge(int x,int y){
int rtx=find(x), rty=find(y);
if(space[rtx].size()>space[rty].size()){
par[rty]=rtx;
set<PI> &X=space[rty],&Y=space[rtx];
for(set<PI>::iterator i=X.begin();i!=X.end();i++) Y.insert(*i);
X.clear();
}else{
par[rtx]=rty;
set<PI> &X=space[rtx],&Y=space[rty];
for(set<PI>::iterator i=X.begin();i!=X.end();i++) Y.insert(*i);
X.clear();
}
}
}ds;
int g(int x,int y){
if(mp.find(make_pair(x,y))==mp.end()) return -1;
return mp[make_pair(x,y)];
}
void remove(int x,int y,int c){
queue<PI > que;
que.push(make_pair(x,y));
while(!que.empty()){
PI u=que.front();
que.pop();
mp.erase(u);
for(int i=0;i<4;i++){
int xx=u.first+dx[i],yy=u.second+dy[i];
if(xx<=0 || yy<=0) continue;
PI v=make_pair(xx,yy);
if(g(xx,yy)==c) que.push(v);
else if(g(xx,yy)==(c^1)) space[ds.find(id[v])].insert(u);
}
}
}
void put(int x,int y,int c){
PI u=make_pair(x,y);
mp[u]=c;
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(xx<=0 || yy<=0) continue;
PI v=make_pair(xx,yy);
if(g(xx,yy)==c) ds.merge(id[u],id[v]);
else if(g(xx,yy)==-1) space[ds.find(id[u])].insert(v);
else{
space[ds.find(id[v])].erase(u);
if(space[ds.find(id[v])].size()==0) remove(xx,yy,c^1);
}
}
space[ds.find(id[u])].erase(u);
if(space[ds.find(id[u])].size()==0) remove(x,y,c);
}
int main(){
int n,re,x,y;
scanf("%d",&re);
while(re--){
scanf("%d",&n);
mp.clear(), id.clear(), ds.init(n);
for(int i=1;i<=n;i++) space[i].clear();
for(int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
id[make_pair(x,y)]=i;
put(x,y,i%2);
}
int B=0,W=0;
map<PI,int>::iterator i=mp.begin();
for(;i!=mp.end();i++) if(i->second==0) W++; else B++;
printf("%d %d\n",B,W);
}
return 0;
}