zoukankan      html  css  js  c++  java
  • UVa 11134

    链接:

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2075

    题意:

    你的任务是在n*n的棋盘上放n(n≤5000)个车,使得任意两个车不相互攻击,且第i个车在一个给定的矩形Ri之内。
    用4个整数xli, yli, xri, yri(1≤xli≤xri≤n,1≤yli≤yri≤n)描述第i个矩形,其中(xli,yli)是左上角坐标,(xri,yri)是右下角坐标,
    则第i个车的位置(x,y)必须满足xli≤x≤xri,yli≤y≤yri。如果无解,输出IMPOSSIBLE;否则输出n行,依次为第1,2,…,n个车的坐标。

    分析:

    问题分解 + 贪心
    两个车相互攻击的条件是处于同一行或者同一列,因此不相互攻击的条件就是不在同一行,也不在同一列。
    可以看出:行和列是无关的,因此可以把原题分解成两个一维问题。在区间[1~n]内选择n个不同的整数,使得第i个整数在闭区间[Li, Ri]内。
    贪心策略:以x坐标为例。对于每个区间来说,都应优先选择较左边的点,这样可以最大程度地利用各个点。
    首先按R值从小到大排序,这样可以避免R值较大的区间比R值较小的区间首先占据较左边的点,即优先考虑较左边的区间,让选择的空间增加。
    再按L值从小到大排序,也是为了最大程度地利用各个点,让选择的空间增加。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int UP = 5000 + 5;
     7 
     8 int n, coor, ans[UP][2];
     9 
    10 struct RANGE {
    11     int id, L[2], R[2];
    12     bool operator < (const RANGE& that) const {
    13         if(R[coor] != that.R[coor]) return R[coor] < that.R[coor];
    14         return L[coor] < that.L[coor];
    15     }
    16 } ran[UP];
    17 
    18 bool solve(int coor){
    19     sort(ran, ran + n);
    20     bool used[UP];
    21     memset(used, false, sizeof(used));
    22     for(int t, i = 0; i < n; i++){
    23         for(t = ran[i].L[coor]; t <= ran[i].R[coor]; t++){
    24             if(used[t]) continue;
    25             used[t] = true;
    26             ans[ran[i].id][coor] = t;
    27             break;
    28         }
    29         if(t > ran[i].R[coor]) return false;
    30     }
    31     return true;
    32 }
    33 
    34 int main(){
    35     while(scanf("%d", &n) && n){
    36         for(int i = 0; i < n; i++){
    37             ran[i].id = i;
    38             scanf("%d%d", &ran[i].L[0], &ran[i].L[1]);
    39             scanf("%d%d", &ran[i].R[0], &ran[i].R[1]);
    40         }
    41         if(!solve(coor = 0) || !solve(coor = 1)) printf("IMPOSSIBLE
    ");
    42         else for(int i = 0; i < n; i++) printf("%d %d
    ",ans[i][0],ans[i][1]);
    43     }
    44     return 0;
    45 }
  • 相关阅读:
    RedHat Linux下利用sersync进行实时同步数据
    curl网站开发指南
    常用命令
    Linux 查看CPU信息、机器型号等硬件信息
    -bash: crontab: command not found(转)
    端口映射工具--socat
    左右半透明的无缝滚动
    js学习笔记33----DOM操作
    Framework 7 之 给Picker Modal 添加半透明背景
    网页嵌入自定义字体方法
  • 原文地址:https://www.cnblogs.com/hkxy125/p/8048163.html
Copyright © 2011-2022 走看看