HDU 4775 Infinite Go

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;
}


你可能感兴趣的:(HDU)