您的位置:首页 > 其它

Codeforces Round #295 (Div. 2) D.Cubes(STL)

2015-03-10 17:03 399 查看
题目:

http://codeforces.com/problemset/problem/520/D

题意:

有n 个点坐标(xi,yi)在坐标平面内,分别编号0~m.

在图上取点,每一次都要使图平衡.平衡的条件是:点(x,y) 在x 轴上,或者是(x,y-1) / (x-1,y-1) / (x+1, y-1) 上有点存在.

现在有两人a和b玩游戏, a先取数,每次取数都要保持图平衡.取到的数组成n进制的数.a要使得数越大,b使得数越小.

思路:

看了别人的代码了解的思路.

使用map存储所有的点坐标和编号.

先枚举所有的点,判断是否可以取,若可以则加入set -leap.

接着开始取数, i 为偶时,从leaf 尾取数, 奇时从头取数. 每次取完, 都要删除leaf中的标号, 且更新与它相关联的点, 看是否可以存在set中被取数.

AC.

#include <iostream>
#include <cstdio>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
const ll mod = 1e9 + 9;
const int MAX = 100005;
map<pair<int, int>, int> ma;
set<pair<int, int> > s;
set<int> leaf;
int x[MAX], y[MAX], n;

void read()
{
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%d %d", &x[i], &y[i]);
pair<int, int> p = make_pair(x[i], y[i]);
ma[p] = i;
s.insert(p);
}
}
int cnt(int xx, int yy)
{
int res = 0;
for(int i = xx - 1; i <= xx + 1; ++i) {
if(s.find(make_pair(i, yy - 1)) != s.end()) res++;
}
return res;
}
bool isleaf(int xx, int yy)
{
for(int i = xx - 1; i <= xx + 1; ++i) {
if(s.find(make_pair(i, yy+1)) != s.end() &&
cnt(i, yy+1) == 1) return false;
}
return true;
}
void update(int xx, int yy)
{
for(int i = xx - 2; i <= xx + 2; ++i) {
for(int j = yy - 1; j <= yy + 1; ++j) {
pair<int, int> p = make_pair(i, j);
if(s.find(p) == s.end()) continue;
int id = ma[p];
if(leaf.find(id) != leaf.end()) leaf.erase(id);
if(isleaf(i, j)) leaf.insert(id);
}
}
}
void work()
{
for(int i = 0; i < n; ++i) {
if(isleaf(x[i], y[i])) leaf.insert(i);
}

ll ans = 0;
for(int i = 0; i < n; ++i) {
int num;
if(i % 2 == 0) num = *(--leaf.end());
else num = *(leaf.begin());
ans = (ans*n + num) % mod;
s.erase(make_pair(x[num], y[num]));
leaf.erase(num);
update(x[num], y[num]);
}

printf("%I64d\n", ans);
}
int main()
{
//freopen("in", "r", stdin);

read();
work();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces