520D

模拟

很明显应该尽量选最大或最小的数。那么我们维护一个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;
}
View Code
原文地址:https://www.cnblogs.com/19992147orz/p/7152969.html