zoukankan      html  css  js  c++  java
  • 01_传说中的车(Fabled Rooks UVa 11134 贪心问题)

    问题来源:刘汝佳《算法竞赛入门经典--训练指南》 P81:

    问题描述:你的任务是在n*n(1<=n<=5000)的棋盘上放n辆车,使得任意两辆车不相互攻击,且第i辆车在一个给定的矩形R之内。

    问题分析:1.题中最关键的一点是每辆车的x坐标和y坐标可以分开考虑(他们互不影响),不然会变得很复杂,则题目变成两次区间选点问题:使得每辆车在给定的范围内选一个点,任何两辆车不能选同一个点。

           2.本题另外一个关键点是贪心法的选择,贪心方法:对所有点的区间,按右端点从小到大排序;每次在一个区间选点的时候,按从左到右选没有被前面区间选过的点。(从这个区间开始选最大程度的防止了以后的区间没有点可以选(因为右端点选的是最小的))

           错误的贪心方法:把所有区间按左端排序,然后每次选能选的最左边的。反例:[1,1],[1,3],[2,2];(这种贪心发并不能保证以后的区间有点可以选,某些区间可能更长,取后面的点更合适)

    例题链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2075

    例题:UVa 11134

    11134 - Fabled Rooks

    Time limit: 3.000 seconds

    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 (xliyli) and its right-lower corner (xriyri), where 1 ≤ i ≤ n, 1 ≤ xli ≤ xri ≤ n, 1 ≤ yli ≤ yri ≤ n.
    • No two rooks can attack each other, that is no two rooks can occupy the same column or the same row.

    The input consists of several test cases. The first line of each of them contains one integer number, n, the side of the board. n lines follow giving the rectangles where the rooks can be placed as described above. The i-th line among them gives xliylixri, and yri. The input file is terminated with the integer `0' on a line by itself.

    Your task is to find such a placing of rooks that the above conditions are satisfied and then output n lines each giving the position of a rook in order in which their rectangles appeared in the input. If there are multiple solutions, any one will do. Output IMPOSSIBLE if there is no such placing of the rooks.

    Sample input

    8
    1 1 2 2
    5 7 8 8
    2 2 5 5
    2 2 5 5
    6 3 8 6
    6 3 8 5
    6 3 8 8
    3 6 7 8
    8
    1 1 2 2
    5 7 8 8
    2 2 5 5
    2 2 5 5
    6 3 8 6
    6 3 8 5
    6 3 8 8
    3 6 7 8
    0
    

    Output for sample input

    1 1
    5 8
    2 4
    4 2
    7 3
    8 5
    6 6
    3 7
    1 1
    5 8
    2 4
    4 2
    7 3
    8 5
    6 6
    3 7

    代码实现:

     1 #include "stdio.h"
     2 #include "string.h"
     3 #include "algorithm"
     4 using namespace std;
     5 
     6 #define N 5010
     7 
     8 typedef struct
     9 {
    10     int id;
    11     int l,r;
    12 }Point;
    13 
    14 int n;
    15 bool mark[N];
    16 Point x[N],y[N],ans[N];
    17 Point ansx[N],ansy[N];
    18 
    19 bool cmp(Point a,Point b) { return a.r < b.r; }  //按右端点最小的进行排序
    20 
    21 bool cmp1(Point a,Point b){ return a.id < b.id;} //按id号还原顺序
    22 
    23 bool solve(Point *a,Point *ans)
    24 {
    25     int i,j;
    26     memset(mark,false,sizeof(mark));
    27     for(i=0; i<n; i++)
    28     {
    29         for(j=a[i].l; j<=a[i].r; j++)
    30         {
    31             if(mark[j]) continue;
    32             break;
    33         }
    34         if(j>a[i].r) return false;
    35         ans[i].l = j; //用ans[i].l保存答案
    36         ans[i].id = a[i].id;
    37         mark[j] = true;
    38     }
    39     return true;
    40 }
    41 
    42 int main()
    43 {
    44     int i;
    45     while(~scanf("%d",&n),n!=0)
    46     {
    47         for(i=0; i<n; i++)
    48         {
    49             scanf("%d %d %d %d",&x[i].l,&y[i].l,&x[i].r,&y[i].r);
    50             x[i].id = y[i].id = i;
    51         }
    52         sort(x,x+n,cmp);
    53         sort(y,y+n,cmp);
    54         if(solve(x,ansx) && solve(y,ansy))
    55         {
    56             sort(ansx,ansx+n,cmp1);
    57             sort(ansy,ansy+n,cmp1);
    58             for(i=0; i<n; i++)
    59                 printf("%d %d
    ",ansx[i].l,ansy[i].l);
    60         }
    61         else
    62             printf("IMPOSSIBLE
    ");
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    跨境电商ERP中的自动化 5.平台订单自动打印面单
    小特工具箱新增功能:文档转换、代码转换和AI写诗词
    跨境电商ERP中的自动化 4.平台订单自动取运单号
    C#.NET 使用HttpWebRequest发送JSON
    .net core .net5 asp.net core mvc 与quartz.net 3.3.3 新版本调用方式
    .NET CORE .NET5 控制台程序使用EF连接MYSQL
    C#.NET 国密SM3withSM2签名与验签 和JAVA互通
    JAVA RSA 私钥签名 公钥验证签名 公钥验签
    java 读取控制台输入
    C#.NET RSA 私钥签名 公钥验证签名
  • 原文地址:https://www.cnblogs.com/ruo-yu/p/4393850.html
Copyright © 2011-2022 走看看