UVA 11134 - Fabled Rooks(经典贪心)

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

【题意】
你的任务是在n×n的棋盘上放置n辆车,使得任意两辆车不互相攻击,且第i辆车在一个给定的矩形Ri以内。

【输入格式】
多组输入。第一行为整数n(1<=n<=5000),以下n行每行4个整数xli,yli,xri,yri(1<=xli<=xri<=n,1<=yli<=yri<=n)描述一个矩形,其中(xli,xri)是左上角坐标,(xri,yri)是右下角坐标。第i个车的位置必须满足xli<=x<=xri,yli<=y<=yri,输入结束标志为n=0

【输出格式】
无解输出”IMPOSSIBLE”,否则依次按照输入顺序输出n个车的坐标,输出任意解即可。

【思路】
首先行列可以分开考虑,它们互不影响,单单考虑行的话,其实就是给定若干个区间,然后给每个区间都分配一个点,使得点不重复的情况下都能落在相应区间中,可以对区间按右端点升序排序,右端点相等时按左端点升序排序,从左往右看每个区间,尽量往区间的左端点分配即可.

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

const int maxn=5050;

struct node{
    int id,le,ri;
    node(int i,int l,int r):id(i),le(l),ri(r){}
    bool operator<(const node& e)const{
        if(ri==e.ri) return le<e.le;
        return ri<e.ri;
    }
};

int n;
vector<node>x,y;
bool used[maxn];
int ansx[maxn],ansy[maxn];

int main(){
    while(scanf("%d",&n)==1 && n){
        x.clear();
        y.clear();
        for(int i=0;i<n;++i){
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            x.push_back(node(i,x1,x2));
            y.push_back(node(i,y1,y2));
        }
        bool ok=1;
        sort(x.begin(),x.end());
        memset(used,0,sizeof(used));
        for(int i=0;i<x.size();++i){
            bool flag=0;
            for(int j=x[i].le;j<=x[i].ri;++j){
                if(!used[j]){ 
                    flag=1;
                    used[j]=1;
                    ansx[x[i].id]=j;
                    break; 
                }
            }
            if(!flag){ ok=0;break; }
        }
        if(ok){
            sort(y.begin(),y.end());
            memset(used,0,sizeof(used));
            for(int i=0;i<y.size();++i){
                bool flag=0;
                for(int j=y[i].le;j<=y[i].ri;++j){
                    if(!used[j]){ 
                        flag=1;
                        used[j]=1;
                        ansy[y[i].id]=j;
                        break;
                    }
                }
                if(!flag){ ok=0;break; }
            }
        }
        if(!ok) puts("IMPOSSIBLE");
        else for(int i=0;i<n;++i){ printf("%d %d\n",ansx[i],ansy[i]); }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xiao_k666/article/details/81272750