uva 11134 - Fabled Rooks(主要在贪心方法及其实现)

#用到了贪心方法。

#这个贪心刚开始想错了方法,后来想到了新的方法,AC

刚开始错在了按左端点升序排序并从左往右取最左端能取的格子,这个方法显然不能符合要求

比如下面这组数据:

2

1 1 3 3

1 1 3 3

2 2 2 2

错误代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;

struct note
{
    int x1,x2,y1,y2,x,y;
    int num;
} a[5010];

bool cmp1(note aa,note bb)
{
    if(aa.x1!=bb.x1) return aa.x1<bb.x1;
    else
        return aa.x2<bb.x2;
}
bool cmp2(note aa,note bb)
{
    if(aa.y1!=bb.y1) return aa.y1<bb.y1;
    else
        return aa.y2<bb.y2;
}
bool cmp3(note aa,note bb)
{
    return aa.num<bb.num;
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        memset(a,0,sizeof(a));
        for(int i=0; i<n; i++)
        {
            int a1,b1,a2,b2;
            scanf("%d%d%d%d",&a1,&b1,&a2,&b2);
            a[i].num=i;
            a[i].x1=a1;
            a[i].x2=a2;
            a[i].y1=b1;
            a[i].y2=b2;
        }
        int flag=1;
        sort(a,a+n,cmp1);

        for(int i=0; i<n; i++)
        {
            if(a[i].x1<=i+1&&a[i].x2>=i+1) a[i].x=i+1;
            else
            {
                flag=0;
                break;
            }
        }
        if(flag!=0)
        {
            sort(a,a+n,cmp2);
            for(int i=0; i<n; i++)
            {
                if(a[i].y1<=i+1&&a[i].y2>=i+1) a[i].y=i+1;
                else
                {
                    flag=0;
                    break;
                }
            }
        }
        if(flag==0)
        {
            printf("IMPOSSIBLE\n");
        }
        else
        {
            sort(a,a+n,cmp3);
            for(int i=0; i<n; i++)
            {
                printf("%d %d\n",a[i].x,a[i].y);
            }
        }
    }
    return 0;
}

后来换了方法,换成按右端点升序排序,从左往右取最左端能取的格子。这个方法用到了一个vis标记数组,不要忘记清零。

AC代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;

struct note
{
    int x1,x2,y1,y2,x,y;
    int num;
} a[5010];

int vis[5010];

bool cmp1(note aa,note bb)
{
    if(aa.x2!=bb.x2) return aa.x2<bb.x2;
    else
        return aa.x1>bb.x1;
}
bool cmp2(note aa,note bb)
{
    if(aa.y2!=bb.y2) return aa.y2<bb.y2;
    else
        return aa.y1>bb.y1;
}
bool cmp3(note aa,note bb)
{
    return aa.num<bb.num;
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        memset(a,0,sizeof(a));

        for(int i=0; i<n; i++)
        {
            int a1,b1,a2,b2;
            scanf("%d%d%d%d",&a1,&b1,&a2,&b2);
            a[i].num=i;
            a[i].x1=a1;
            a[i].x2=a2;
            a[i].y1=b1;
            a[i].y2=b2;
        }
        int flag=1;
        sort(a,a+n,cmp1);

        memset(vis,0,sizeof(vis));
        for(int i=0; i<n; i++)
        {
            int temp1=a[i].x1;
            int temp2=a[i].x2;
            int flag1=0;
            for(int j=temp1; j<=temp2; j++)
            {
                if(!vis[j])
                {
                    a[i].x=j;
                    flag1=1;
                    vis[j]=1;
                    break;
                }
            }
            if(!flag1)
            {
                flag=0;
                break;
            }
        }
        memset(vis,0,sizeof(vis));
        if(flag!=0)
        {
            sort(a,a+n,cmp2);
            for(int i=0; i<n; i++)
            {
                int temp1=a[i].y1;
                int temp2=a[i].y2;
                int flag1=0;
                for(int j=temp1; j<=temp2; j++)
                {
                    if(!vis[j])
                    {
                        a[i].y=j;
                        flag1=1;
                        vis[j]=1;
                        break;
                    }
                }
                if(!flag1)
                {
                    flag=0;
                    break;
                }
            }
        }
        if(flag==0)
        {
            printf("IMPOSSIBLE\n");
        }
        else
        {
            sort(a,a+n,cmp3);
            for(int i=0; i<n; i++)
            {
                printf("%d %d\n",a[i].x,a[i].y);
            }
        }
    }
    return 0;
}

uva 11134 - Fabled Rooks(主要在贪心方法及其实现)

时间: 2024-11-25 23:41:51

uva 11134 - Fabled Rooks(主要在贪心方法及其实现)的相关文章

Uva 11134 Fabled Rooks (问题分解 + 贪心放置)

题意: 给你n*n的棋盘,让放置n个车 使他们之间并不能相互攻击 附加条件是 给定n个车的放置区间 用左上角和右下角的坐标来表示 解题思路: 首先明确 横向的约束和纵向的约束其实并不互相影响 所以可以对横向和纵向单独求解 把问题变成两个一维的区间选点问题来求解 另外 在取点的时候 有贪心的思路在里面 对于n个区间 应该先选择区间中r最小的区间进行放置可放置的点 可以简单认为这是因为r越小的区间 其选择的灵活性就越低. 我刚开始的时候 是采取了先放置区间长度小的 在放置l小的区间 不正确. cod

UVA - 11134 Fabled Rooks[贪心 问题分解]

UVA - 11134 Fabled Rooks 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 rectan- gle given by its left-upper corner (xli,yli) and its right- lower corner

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

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

UVa 11134 Fabled Rooks(贪心)

题意  在n*n的棋盘上的n个指定区间上各放1个'车'  使他们相互不攻击   输出一种可能的方法 行和列可以分开看  就变成了n个区间上选n个点的贪心问题  看行列是否都有解就行   基础的贪心问题  对每个点选择包含它的最优未使用空间 #include <bits/stdc++.h> using namespace std; const int N = 5005; int xl[N], yl[N], xr[N], yr[N], x[N], y[N], n; bool solve(int a

UVA 11134 - Fabled Rooks(贪心 / 二分图 + 线段树优化连边)

题目地址:Fabled Rooks 题目大意:n * n 的棋盘上摆了 n <=10^5 个车,让他们两两不攻击,每个车必须摆在一个给定矩形里,给出一个解决方案? 1. 贪心 由于行列互不影响, 所以可以分两遍求.第一遍确定每个车的行数,第二遍确定列数. 以行为例,若从左到右扫描,则按照区间的右端点升序排序,因为如果扫到一个位置两枚棋子都可以放,则选择右端点较小的那个(右端点大的后面还有机会). 2. 二分图匹配 有个毒瘤老师把题目改成了这样:n * n 的棋盘上摆了 n <=10^5 个车,

UVA 11134 Fabled Rooks 贪心

题目链接:UVA - 11134 题意描述:在一个n*n(1<=n<=5000)的棋盘上放置n个车,每个车都只能在给定的一个矩形里放置,使其n个车两两不在同一行和同一列,判断并给出解决方案. 算法分析:刚开始没有思路,后来看了别人的博客有了一点想法.我们把矩形的行和列分开解决,即n个车首先不能放置在同一行,然后判断n个车不能放置在同一列,如果都满足的话,即有正确的方法,否则就不行.那么怎样解决和判断在不在同一行并且是否可行呢,我们针对行而言,把这些行的坐标存入优先队列,首先取出最上面(行的标号

uva 11134 fabled rooks (贪心)——yhx

We would like to place n rooks, 1 n 5000, on a n nboard subject to the following restrictions• The i-th rook can only be placed within the rectan-gle given by its left-upper corner (xli; yli) and its right-lower corner (xri; yri), where 1 i n, 1 xli

UVA 11134 Fabled Rooks(贪心的妙用+memset误用警示)

题目链接: https://cn.vjudge.net/problem/UVA-11134 1 /* 2 问题 输入棋盘的规模和车的数量n(1=<n<=5000),接着输入n辆车的所能在的矩阵的范围,计算并输出使得每辆车横竖都不能相互攻击 3 的摆放方法,能则输出每辆车的坐标,不能则输出"IMPOSSIBLE". 4 解题思路 想想怎么将问题分解成几个小问题,不同行不同列的话,将其分成两个一维问题,采用DFS向下搜索,搜的时候注意每个车的 5 行区间和列区间,找到一种则直接

UVa 11134 - Fabled Rooks——[问题分解、贪心法]

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 rightlower corner (xri, yri), where 1 ≤ i ≤