codeforces 520d Cubes 贪心+set

来源:互联网 发布:北京 抑郁症 知乎 编辑:程序博客网 时间:2024/06/03 11:19

题意:

把一些1*1的方形放在二维平面上,每个方形有唯一的编号值(0~m-1),y = 0为地面。

现在给出每个方形左下角的坐标(一开始构成的图保持稳定),两个人轮流把它们拆卸下来,从左到右摆放,并且保证拆卸过程方块保持稳定。

方形上的每个数值都是m进制,转换成十进制并且模上10^+9.

先手希望最后的值大,后手希望最后的值小。


思路:

一开始题意都看不大懂,后来翻了下别人的题意还有思路。

一个很明显的贪心。

1.开始我们先把能够拆卸的方形放到set中,然后根据先后手的情况从set的前后取出方形进行拆卸(set自有顺序)。

(注意一点:即使是在set里面的方形,也可能是不可以拆卸的。因此要对set里面取出的方形进行判断是否能拆卸。直到能够找到一个可拆卸的方形。)

2.在拆卸完一个方形之后,判断这个方形的下面3个方形是否能拆卸,能则扔到set里面。

3.直到拆卸完m个方形。


code:

#include <bits/stdc++.h>using namespace std;const int N = 1e5+5;const int MOD = 1e9+9;typedef long long LL;struct PP {    int x, y;}a[N];typedef pair<int, int> pa;map <pair<int, int>, int> mp;set <int> st;int res[N];int n;int up[3][2] = {{0, 1}, {-1, 1}, {1, 1}};int down[3][2] = {{0, -1}, {-1, -1}, {1, -1}};//int gcount(const pa& t) {    int x, y;    int ret = 0;    for(int i = 0;i < 3; i++) {        x = t.first+down[i][0], y = t.second+down[i][1];        pa tmp = make_pair(x, y);        if(mp.find(tmp) != mp.end()) ret++;    }    return ret;}bool candes(int i) {    bool flag = true;    int x, y;    for(int j = 0;j < 3; j++) {        x = a[i].x+up[j][0], y = a[i].y+up[j][1];        pa tmp = make_pair(x,y);        if(mp.find(tmp) != mp.end() && gcount(tmp) <= 1)            return false;    }    return true;}int low() {    //begin    auto it = st.begin();    int tmp;    while(!st.empty()) {        it = st.begin();        if(candes(*it)) {             tmp = *it;            st.erase(it);            break;        }        st.erase(it);    }    mp.erase(make_pair(a[tmp].x, a[tmp].y));    int x,y;    for(int i = 0;i < 3; i++) {        x = a[tmp].x+down[i][0], y = a[tmp].y+down[i][1];        pa tp = make_pair(x, y);        auto it = mp.find(tp);        if(it != mp.end() && candes(it->second))            st.insert(it->second);    }    return tmp;}int upp() {    //end    auto it = st.end();    int tmp;    while(!st.empty()) {        it = st.end();        it--;        if(candes(*it)) {            tmp = *it;            st.erase(it);            break;        }        st.erase(it);    }    mp.erase(make_pair(a[tmp].x, a[tmp].y));        int x, y;    for(int i = 0;i < 3; i++) {        x = a[tmp].x+down[i][0], y = a[tmp].y+down[i][1];        pa tp = make_pair(x, y);        auto it = mp.find(tp);        if(it != mp.end() && candes(it->second))            st.insert(it->second);    }    return tmp;}        int solve() {    int x, y;    for(int i = 0;i < n; i++) {        if(candes(i)) st.insert(i);    }       //    for(int i = 0;i < n; i++) {        res[i] = i&1?low():upp();    }    //    LL ret = 0, xx = 1;    for(int i = n-1;i >= 0; i--) {        ret = (ret+(LL)res[i]*xx)%MOD;        xx = (xx*n)%MOD;    }    return (int)ret;}                int main() {    scanf("%d", &n);    int x, y;    for(int i = 0;i < n; i++) {        scanf("%d%d", &x, &y);        a[i] = (PP){x, y};        mp[make_pair(x, y)] = i;    }    printf("%d\n", solve());    return 0;}



0 0