UVA 11134

voj的链接http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34086

方法 贪心或者优先队列

贪心的题目, 一开始认为是水题 后来想到了这种情况


  **

*****

 *****

所以按照x1排列就错了,应该按照x2排列,求最左边的值,因为x2越小的越受限制,水题,不多写了

贪心AC代码:

#include<iostream>
#include<vector>
#include<string>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<cstdio>
#include<cstdlib>

using namespace std;
int n;
struct Edge{
    int x1, y1, x2, y2;
    int px, py;
    int th;
}e[5005];
bool vis[5005];

bool cmp1(Edge u, Edge v){
    return u.x2<v.x2||(u.x2==v.x2&&u.x1<v.x1);
}

bool cmp2(Edge u, Edge v){
    return u.y2<v.y2||(u.y2==v.y2&&u.y1<v.y1);
}

bool cmp3(Edge u, Edge v){
    return u.th<v.th;
}

int main(){
    while(~scanf("%d", &n), n){
        for(int i=0; i<n;++i){
            scanf("%d%d%d%d", &e[i].x1, &e[i].y1, &e[i].x2, &e[i].y2);
            e[i].th=i;
        }

        bool possible=true;

        sort(e, e+n, cmp1);
        memset(vis, 0 ,sizeof(vis));
        for(int i=0; i<n; ++i){
            int l=e[i].x1, r=e[i].x2;
            bool finded=false;
            for(int j=l; j<=r; ++j)
            if(vis[j]==false){
                vis[j]=finded=true;
                e[i].px=j;
                break;
            }
            if(finded==false) { possible=false; break;}
        }

        sort(e, e+n, cmp2);
        memset(vis, 0 ,sizeof(vis));
        for(int i=0; i<n; ++i){
            int l=e[i].y1, r=e[i].y2;
            bool finded=false;
            for(int j=l; j<=r; ++j)
            if(vis[j]==false){
                vis[j]=finded=true;
                e[i].py=j;
                break;
            }
            if(finded==false) { possible=false; break;}
        }

        if(possible){
            sort(e, e+n, cmp3);
            for(int i =0;i<n;++i){
                printf("%d %d\n",e[i].px, e[i].py);
            }
        }
        else{
            printf("IMPOSSIBLE\n");
        }
    }
    return 0;
}

优先队列AC代码以后补上:

**********

**********

**********

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值