模拟
很明显应该尽量选最大或最小的数。那么我们维护一个set,再维护一个mp,每次检查是否能选,如果选完这个数上面的东西不悬空就可以选,每次选完都要更新四周-2+2的方块,因为再远就影响不到了
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> PII; const int N = 100010, mod = 1000000009; int m; ll ans; map<PII, int> mp; PII mir[N]; set<int> s; int x[N], y[N]; int down(int x, int y) { int ret = 0; if(mp.find(make_pair(x, y)) == mp.end()) return 5; for(int i = -1; i <= 1; ++i) if(mp.find(make_pair(x + i, y - 1)) != mp.end()) ++ret; return ret; } bool check(int i) { int x = mir[i].first, y = mir[i].second; if(down(x - 1, y + 1) > 1 && down(x, y + 1) > 1 && down(x + 1, y + 1) > 1) return true; return false; } void update(int p) { int x = mir[p].first, y = mir[p].second; for(int i = -2; i <= 2; ++i) for(int j = -2; j <= 2; ++j) { if(mp.find(make_pair(x + i, y + j)) == mp.end()) continue; if(!check(mp[make_pair(x + i, y + j)])) s.erase(mp[make_pair(x + i, y + j)]); else s.insert(mp[make_pair(x + i, y + j)]); } } int main() { scanf("%d", &m); for(int i = 0; i < m; ++i) { scanf("%d%d", &x[i], &y[i]); mir[i] = make_pair(x[i], y[i]); s.insert(i); mp[make_pair(x[i], y[i])] = i; } for(int z = 0; !s.empty(); z ^= 1) { set<int> :: iterator it; while(true) { if(z == 0) it = --s.end(); else it = s.begin(); if(check(*it)) break; s.erase(it); } mp.erase(mir[*it]); update(*it); ans = (ans * m + *it) % mod; s.erase(it); } printf("%lld ", ans); return 0; }