UVA - 11134 Fabled Rooks(简单贪心)

13 篇文章 0 订阅

题目链接:https://cn.vjudge.net/problem/UVA-11134

这题和我之前做的多校上的一题十分像,就是一个贪心。具体可以先看看这篇bolg:https://blog.csdn.net/super_son/article/details/80330290

这和多校那题很像,唯一不同就是多了一步分析,这里的行和列是无关的,所以我们可以把行和列分开来看,行进行一次贪心,列进行一次贪心,这就和多校那题解题思路差不多了。

所以这题可以和多校那题一样使用优先队列解决,代码如下:

#include <bits/stdc++.h>
using namespace std;

struct Node{
    int id, x, y;
    Node(int id=0, int x=0, int y=0):id(id),x(x),y(y){}
    bool operator > (const Node& n) const{
        return y > n.y || (y == n.y && x > n.x);
    }
};

const int maxn = 5000 + 10;
Node r[maxn], c[maxn], ans[maxn];

int main(){
    int n;
    while(cin >> n && n){

        for(int i = 1; i <= n; ++i){
            r[i].id = c[i].id = i;
            cin >> r[i].x >> c[i].x >> r[i].y >> c[i].y;
        }

        int cnt = 1;
        priority_queue<Node, vector<Node>, greater<Node> > qr;
        priority_queue<Node, vector<Node>, greater<Node> > qc;
        while(cnt <= n){
            for(int i = 1; i <= n; ++i)
                if(r[i].x == cnt) qr.push(r[i]);
            for(int i = 1; i <= n; ++i)
                if(c[i].x == cnt) qc.push(c[i]);

            if(!qr.empty()) {
                int t = qr.top().id;
                qr.pop();
                if(r[t].y >= cnt) ans[t].x = cnt;
                else { cnt = 0; break; }
            } else {
                cnt = 0;
                break;
            }

            if(!qc.empty()) {
                int t = qc.top().id;
                qc.pop();
                if(c[t].y >= cnt) ans[t].y = cnt;
                else { cnt = 0; break; }
            } else {
                cnt = 0;
                break;
            }

            cnt++;
        }

        if(cnt) {
            for(int i = 1; i <= n; ++i)
                cout << ans[i].x << " " << ans[i].y << endl;
        }else {
            cout << "IMPOSSIBLE" << endl;
        }
    }
    return 0;
}

由于这题的特殊性,因为每个Rook都必须要有个位置能放下,否则就直接输出-1。所以我们就可以按照那些Ronk的右端点对Rook进行从小到大的排序,然后按照这个顺序依次为每个Ronk安排位置,这样一来一旦某个Rook无法安排下了,就直接输出-1。代码如下:

#include <bits/stdc++.h>
using namespace std;

struct Interval{
    int L, R, id;
    bool operator < (const Interval& p) const {
        return R < p.R || (R == p.R && L < p.L);
    }
};

const int maxn = 5005;
int n, vis[maxn];

bool solve(Interval t[], int a[]){
    sort(t+1, t+1+n);
    memset(vis, 0, sizeof(vis));
    for(int j,i = 1; i <= n; ++i){
        for(j = t[i].L; j <= t[i].R; ++j)
            if(!vis[j]){
                vis[j] = 1;
                a[t[i].id] = j;
                break;
            }
        if(j > t[i].R) return false;
    }
    return true;
}

int main(){
    Interval r[maxn], c[maxn];
    while(scanf("%d", &n) != EOF && n){
        for(int i = 1; i <= n; ++i){
            r[i].id = c[i].id = i;
            scanf("%d%d%d%d", &r[i].L, &c[i].L, &r[i].R, &c[i].R);
        }

        int R[maxn], C[maxn];
        if(solve(r, R) && solve(c, C)){
            for(int i = 1; i <= n; ++i)
                printf("%d %d\n", R[i], C[i]);
        }else {
            printf("IMPOSSIBLE\n");
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值