码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces 520D Cubes

时间:2015-03-02 23:59:39      阅读:330      评论:0      收藏:0      [点我收藏+]

标签:codeforces   贪心   

题意:

二维平面内有一个图形由n(10^5)个标有0~n-1的方块组成  保证它是稳定的  即每个方块要么落在地面上  要么下面(边或点相交)有至少一个方块支撑  现在两个人轮流拆这个图形  要求拆的过程中图形仍稳定  拆下的方块上的数字会形成一个n进制的数  先手想让这个数最大  后手想最小  问最后这个数字是几

思路:

简单的贪心思路  在不毁坏稳定性的前提下  先手拿大数字  后手拿小数字  程序写的暴力会n^2造成TLE

那么我们维护一个有序队列(set维护)  这里面装着可以拆的数字  每次从里面拿走想要的数字

注意的是进入set的数字在拆之前仍要检查可行性!  因为最开始可能是_-_这种形状  那么这3个都进入set  假设拆掉了右边  即变成了_-这样  那么这时左边就不能拆了  即使它在set里

每次拆完一个数字  检查它下面的3个位置  这三个位置也许具有拆掉的可能了

PS:

使用STL要小心点  一边遍历一遍删除元素是很危险的!!!

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
typedef long long LL;
#define N 100010
#define mod 1000000009
#define mp(x,y) (make_pair(x,y))

int n;
int x[N],y[N];
map<pair<int,int>,int> f;
set<int> g;
LL ans;

bool yes(int tmp){
	int X,Y;
	X=x[tmp]+1;
	Y=y[tmp]+1;
	if(f.count(mp(X,Y))){
		if(!f.count(mp(X,Y-1))&&!f.count(mp(X+1,Y-1))){
			return false;
		}
	}
	X=x[tmp];
	Y=y[tmp]+1;
	if(f.count(mp(X,Y))){
		if(!f.count(mp(X-1,Y-1))&&!f.count(mp(X+1,Y-1))){
			return false;
		}
	}
	X=x[tmp]-1;
	Y=y[tmp]+1;
	if(f.count(mp(X,Y))){
		if(!f.count(mp(X-1,Y-1))&&!f.count(mp(X,Y-1))){
			return false;
		}
	}
	return true;
}

void add(int tmp){
	int X,Y;
	X=x[tmp]-1;
	Y=y[tmp]-1;
	if(f.count(mp(X,Y))){
		int u=f[mp(X,Y)];
		if(yes(u)) g.insert(u);
	}
	X=x[tmp];
	Y=y[tmp]-1;
	if(f.count(mp(X,Y))){
		int u=f[mp(X,Y)];
		if(yes(u)) g.insert(u);
	}
	X=x[tmp]+1;
	Y=y[tmp]-1;
	if(f.count(mp(X,Y))){
		int u=f[mp(X,Y)];
		if(yes(u)) g.insert(u);
	}
}

int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&x[i]);
		scanf("%d",&y[i]);
		f[mp(x[i],y[i])]=i;
	}
	for(int i=0;i<n;i++){
		if(yes(i)) g.insert(i);
	}
	for(int i=0;i<n;i++){
		if(i&1){
			while(!g.empty()){
				int tmp=(*g.begin());
				if(yes(tmp)){
					ans=((ans*n%mod)+tmp)%mod;
					g.erase(tmp);
					f.erase(mp(x[tmp],y[tmp]));
					add(tmp);
					break;
				}
				g.erase(tmp);
			}
		}else{
			while(!g.empty()){
				int tmp=(*g.rbegin());
				if(yes(tmp)){
					ans=((ans*n%mod)+tmp)%mod;
					g.erase(tmp);
					f.erase(mp(x[tmp],y[tmp]));
					add(tmp);
					break;
				}
				g.erase(tmp);
			}
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


CodeForces 520D Cubes

标签:codeforces   贪心   

原文地址:http://blog.csdn.net/houserabbit/article/details/44025593

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!