UVA11134 Fabled Rooks(贪心)

来源:互联网 发布:photoshop软件介绍 编辑:程序博客网 时间:2024/06/08 09:10

We would like to place n rooks, 1 ≤ n ≤ 5000, on a n×n board subject to the following restrictions
The i-th rook can only be placed within the rectangle given by its left-upper corner (xli, yli) and its right-lower corner (xri, yri), where 1 ≤ i ≤ n, 1 ≤ xli ≤ xri ≤ n, 1 ≤ yli ≤ yri ≤ n.
No two rooks can attack each other, that is no two rooks can occupy the same column or the same row.

The input consists of several test cases. The first line of each of them contains one integer number, n, the side of the board. n lines follow giving the rectangles where the rooks can be placed as described above. The i-th line among them gives xli, yli, xri, and yri. The input file is terminated with the integer `0’ on a line by itself.

Your task is to find such a placing of rooks that the above conditions are satisfied and then output n lines each giving the position of a rook in order in which their rectangles appeared in the input. If there are multiple solutions, any one will do. Output IMPOSSIBLE if there is no such placing of the rooks.

题解:
这个数据规模太大了,所以应当不是搜索,不然怎么都会超时。
这道题的第一个关键点就是,横纵坐标是没有关系的,就是说你横坐标放在哪里和纵坐标都是没有关系的。
所以,现在变成了,我们怎么对横坐标或者是纵坐标贪心才是难点。
正确的原则应当是,对于横坐标,我把棋子能放在左边就尽量放左边(A[i].l),如果有有个横坐标是一样的,那么我们就把棋子放在矩形范围更小(即A[i].r)的那个,这样应当是最优的。因为不会有其他情况更优。

代码:

#include<bits/stdc++.h>using namespace std;const int maxn=5005;struct note {    int l,r,id;    bool operator<(const struct note&aa)const {        return l>aa.l||(l==aa.l&&r>aa.r);    }} A[maxn],B[maxn];int n;pair<int,int> Ans[maxn];bool check(struct note* NOW,int bign) {    priority_queue<note> que;    for(int i=0; i<n; ++i) {        que.push(NOW[i]);    }    int line=0;    while(!que.empty()) {        note temp=que.top();        que.pop();        if(line>temp.r)            return false;        if(temp.l<line) {            temp.l=line;            que.push(temp);            continue;        }        if(bign)            Ans[temp.id].second=temp.l;        else            Ans[temp.id].first=temp.l;        line=temp.l+1;    }    return true;}int main() {    while(scanf("%d",&n)==1,n) {        for(int i=0; i<n; ++i) {            scanf("%d%d%d%d",&A[i].l,&B[i].l,&A[i].r,&B[i].r);            A[i].id=B[i].id=i;        }        if(check(A,0)&&check(B,1)) {            for(int i=0; i<n; ++i) {                printf("%d %d\n",Ans[i].first,Ans[i].second);            }        } else {            printf("IMPOSSIBLE\n");        }    }    return 0;}
1 0
原创粉丝点击