zoukankan      html  css  js  c++  java
  • Problem UVA11134-Fabled Rooks(贪心)

    Problem UVA11134-Fabled Rooks

    Accept: 716  Submit: 6134
    Time Limit: 3000mSec

    Problem Description

    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 ≤ 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.

    Input

    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 xli, yli, xri, and yri. The input file is terminated with the integer ‘0’ on a line by itself.

     Output

    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

    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
     
    题解:有了lrj前面几道关于区间的例题,这个题的贪心还是很好想的,首先因为行列独立,因此可以转化为两个问题分析,在区间1~n之间选n个互不相同的数,使得第i个数在区间[ai,bi].区间排序时按右端点递增排,右端点相同时按左端点从大到小排。每次选取区间最左边能选的点。当有一个区间不能选时就是IMPOSSIBLE.我粗略地证明一下:假设在当前区间不选可选的最左边的点,必定选取了一个更靠右的点,最左边的点肯定也是要填的,之后填这个格子的区间如果是左端点小于等于当前区间的区间,那么交换填的方式不影响可解性,如果左端点大于当前区间左端点,那么当前区间尽量向左填所得到的解不会比当前解差。有不对的地方,欢迎大家指教。
     
     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 5000 + 100;
     6 
     7 int n;
     8 
     9 struct Interval {
    10     pair<int, int> interval;
    11     int pos;
    12 }hor[maxn], ver[maxn];
    13 
    14 bool cmp(const Interval &a, const Interval &b) {
    15     if (a.interval.second == b.interval.second) return a.interval.first > b.interval.first;
    16     else return a.interval.second < b.interval.second;
    17 }
    18 
    19 bool hvis[maxn], vvis[maxn];
    20 int vans[maxn], hans[maxn];
    21 
    22 int main()
    23 {
    24     //freopen("input.txt", "r", stdin);
    25     while (~scanf("%d", &n) && n) {
    26         memset(hvis, false, sizeof(hvis));
    27         memset(vvis, false, sizeof(vvis));
    28         int xl, yl, xr, yr;
    29         for (int i = 1; i <= n; i++) {
    30             scanf("%d%d%d%d", &xl, &yl, &xr, &yr);
    31             ver[i].interval = make_pair(xl, xr);
    32             ver[i].pos = i;
    33             hor[i].interval = make_pair(yl, yr);
    34             hor[i].pos = i;
    35         }
    36 
    37         sort(ver + 1, ver + 1 + n, cmp);
    38         sort(hor + 1, hor + 1 + n, cmp);
    39 
    40         bool ok = true;
    41 
    42         for (int i = 1; i <= n; i++) {
    43             int l = ver[i].interval.first, r = ver[i].interval.second;
    44             int p = ver[i].pos;
    45             int j;
    46             for (j = l; j <= r; j++) {
    47                 if (!vvis[j]) {
    48                     vvis[j] = true;
    49                     vans[p] = j;
    50                     break;
    51                 }
    52             }
    53             if (j == r + 1) { ok = false; break; }
    54         }
    55 
    56         if (!ok) {
    57             printf("IMPOSSIBLE
    ");
    58             continue;
    59         }
    60 
    61         for (int i = 1; i <= n; i++) {
    62             int l = hor[i].interval.first, r = hor[i].interval.second;
    63             int p = hor[i].pos;
    64             int j;
    65             for (j = l; j <= r; j++) {
    66                 if (!hvis[j]) {
    67                     hvis[j] = true;
    68                     hans[p] = j;
    69                     break;
    70                 }
    71             }
    72             if (j == r + 1) { ok = false; break; }
    73         }
    74 
    75         if (!ok) {
    76             printf("IMPOSSIBLE
    ");
    77             continue;
    78         }
    79 
    80         for (int i = 1; i <= n; i++) {
    81             printf("%d %d
    ", vans[i], hans[i]);
    82         }
    83     }
    84     return 0;
    85 }
     

     Sample Output

  • 相关阅读:
    第一次个人编程作业
    软件工程博客作业1
    第一周作业
    预备作业
    没有权限访问路径
    Linux命令:pwd
    Linux命令:readonly
    Linux命令:read
    Bash:精华
    Linux命令:history
  • 原文地址:https://www.cnblogs.com/npugen/p/9623843.html
Copyright © 2011-2022 走看看