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;
}
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 Round #297 (Div. 2) E Anya and Cubes
- 【Codeforces Round 274 (Div 2)D】【STL-SET 讨论】Long Jumps 刻度尺最多加几个刻度使得可以测量X与Y
- Codeforces Round #332 (Div. 2) 599B Spongebob and Joke(STL)
- Codeforces Round #295 (Div. 1)
- Codeforces Round #295 (Div. 2)(A,B,C)
- Codeforces Round #356 (Div. 2)D. Bear and Tower of Cubes
- Codeforces Round #295 (Div. 2)——B——Two Buttons
- Codeforces Round #378 (Div. 2) D. Kostya the Sculptor(STL运用)
- 【Codeforces Round 345 (Div 1) A】【STL-map or stable_sort or双关键字排序】Watchmen 曼哈顿距离=欧几里得距离点对数
- Codeforces Round #Pi (Div. 2) D. One-Dimensional Battle Ships 二分 stl应用
- Codeforces Round #130 (Div. 2) A. Dubstep(STL做法)
- Codeforces Round #295 (Div. 2)-C. DNA Alignment
- Codeforces Round #378 (Div. 2) -- D. Kostya the Sculptor (STL水题)
- Codeforces Round #296 (Div. 2) C(STL_set)
- Codeforces Round #268 (Div. 2) D. Two Sets [stl - set + 暴力]
- Codeforces Round #295 (Div. 2) -- B. Two Buttons (模拟)
- Codeforces Round #295 (Div. 2) E. Pluses everywhere
- 【Codeforces Round 345 (Div 2) B】【贪心 STL-set】Beautiful Paintings 安排顺序使得a[i]大于a[i-1]的i尽可能多
- Codeforces Round #295 (Div. 2) A、B
- Codeforces Round #350 (Div. 2) A B C D E STL (list map stack)