首页 > 代码库 > (白书训练计划)UVa 11134 Fabled Rooks(贪心)

(白书训练计划)UVa 11134 Fabled Rooks(贪心)

题目地址:UVa 11134

这题因为行与列是无关的,互无影响的。所以可以将行或列分开来计算。这就相当于转化成了在期间[1,n]内选择n个不同的整数,使得第i个整数在闭区间[Li,Ri]内。这就转换成了一个贪心问题了。但是注意不能先按照左端点排序,再按右端点排序,然后尽量往左边放,比如,(1,1),(1,3),(2,2),这样是不对的,应该按右端点为主关键字排序,再按左端点为次关键字排序。看到网上的方法全都是用每次选一个数后,都要在后面的区间中删去这个数,还要用到优先队列。。感觉没必要这样做。。只要把排序关键字换换就可以了。

代码如下:

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>

using namespace std;
int a[6000], b[6000], _hash[6000];
struct node
{
    int l, r, num;
}x[100000], y[100000];
int cmp(node x, node y)
{
    if(x.r==y.r) return x.l<y.l;
    return x.r<y.r;
}
int main()
{
    int n, i, j, flag, z;
    while(scanf("%d",&n)!=EOF&&n)
    {
        for(i=0;i<n;i++)
        {
            scanf("%d%d%d%d",&x[i].l,&y[i].l,&x[i].r,&y[i].r);
            x[i].num=i;
            y[i].num=i;
        }
        memset(_hash,0,sizeof(_hash));
        sort(x,x+n,cmp);
        sort(y,y+n,cmp);
        z=0;
        for(i=0;i<n;i++)
        {
            flag=0;
            for(j=x[i].l;j<=x[i].r;j++)
            {
                if(!_hash[j])
                {
                    a[x[i].num]=j;
                    _hash[j]=1;
                    flag=1;
                    break;
                }
            }
            if(!flag)
            {
                z=1;
                break;
            }
        }
        if(z)
        {
            printf("IMPOSSIBLE\n");
            continue ;
        }
        memset(_hash,0,sizeof(_hash));
        z=0;
        for(i=0;i<n;i++)
        {
            flag=0;
            for(j=y[i].l;j<=y[i].r;j++)
            {
                if(!_hash[j])
                {
                    b[y[i].num]=j;
                    _hash[j]=1;
                    flag=1;
                    break;
                }
            }
            if(!flag)
            {
                z=1;
                break;
            }
        }
        if(z)
        {
            printf("IMPOSSIBLE\n");
            continue ;
        }
        for(i=0;i<n;i++)
        {
            printf("%d %d\n",a[i],b[i]);
        }
    }
    return 0;
}


(白书训练计划)UVa 11134 Fabled Rooks(贪心)