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 (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 rst 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 le is terminated with the integer `0' on a line by itself.
Output
Your task is to nd such a placing of rooks that the above conditions are satised 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.


因为行和列并没有什么关系,所以只要把问题分成两个,如果都能满足,再进行配对即可。

那么问题就变成了在[1,n]上有n个区间,把n个整数恰好不重不漏地分配到每个区间。

很明显用贪心。

  1. #include<cstdio>
  2. #include<cstring>
  3. struct qj
  4. {
  5. int l,r,num;
  6. }q1,q2;
  7. qj a1[],a2[];
  8. int p1[],p2[],n;
  9. bool xy(qj a,qj b)
  10. {
  11. return a.l<b.l||(a.l==b.l&&a.r<b.r);
  12. }
  13. void st1(int l,int r)
  14. {
  15. int i,j,k;
  16. qj mid=a1[(l+r)/];
  17. i=l;
  18. j=r;
  19. do
  20. {
  21. while (xy(a1[i],mid)) i++;
  22. while (xy(mid,a1[j])) j--;
  23. if (i<=j)
  24. {
  25. p1[a1[i].num]=j;
  26. p1[a1[j].num]=i;
  27. q1=a1[i];
  28. a1[i]=a1[j];
  29. a1[j]=q1;
  30. i++;
  31. j--;
  32. }
  33. }
  34. while (i<=j);
  35. if (l<j) st1(l,j);
  36. if (i<r) st1(i,r);
  37. }
  38. void st2(int l,int r)
  39. {
  40. int i,j,k;
  41. qj mid=a2[(l+r)/];
  42. i=l;
  43. j=r;
  44. do
  45. {
  46. while (xy(a2[i],mid)) i++;
  47. while (xy(mid,a2[j])) j--;
  48. if (i<=j)
  49. {
  50. p2[a2[i].num]=j;
  51. p2[a2[j].num]=i;
  52. q2=a2[i];
  53. a2[i]=a2[j];
  54. a2[j]=q2;
  55. i++;
  56. j--;
  57. }
  58. }
  59. while (i<=j);
  60. if (l<j) st2(l,j);
  61. if (i<r) st2(i,r);
  62. }
  63. int main()
  64. {
  65. int i,j,k,m,p,q,x,y,z;
  66. bool ok;
  67. while (scanf("%d",&n)&&n)
  68. {
  69. for (i=;i<=n;i++)
  70. {
  71. scanf("%d%d%d%d",&q1.l,&q2.l,&q1.r,&q2.r);
  72. p1[i]=p2[i]=q1.num=q2.num=i;
  73. a1[i]=q1;
  74. a2[i]=q2;
  75. }
  76. st1(,n);
  77. st2(,n);
  78. ok=;
  79. for (i=;i<=n;i++)
  80. if (a1[i].l>i||a1[i].r<i||a2[i].l>i||a2[i].r<i)
  81. {
  82. ok=;
  83. break;
  84. }
  85. if (ok)
  86. for (i=;i<=n;i++)
  87. printf("%d %d\n",p1[i],p2[i]);
  88. else
  89. printf("IMPOSSIBLE\n");
  90. }
  91. }

以上是经典的错误答案。(反正我开始就是这么错的)

把区间按左端点排序,第i个区间放整数i。

反例:[1,1],[1,3],[2,2]。照这个贪心思路找不到解。

  1. #include<cstdio>
  2. #include<cstring>
  3. #define MS(a) memset(a,0,sizeof(a))
  4. int l1[],r1[],l2[],r2[],p1[],p2[];
  5. int main()
  6. {
  7. int i,j,k,m,n,p,q1,q2,x,y,z,min1,min2;
  8. bool ok;
  9. while (scanf("%d",&n)&&n)
  10. {
  11. MS(p1);
  12. MS(p2);
  13. for (i=;i<=n;i++)
  14. scanf("%d%d%d%d",&l1[i],&l2[i],&r1[i],&r2[i]);
  15. ok=;
  16. for (i=;i<=n;i++)
  17. {
  18. q1=q2=-;
  19. min1=min2=;
  20. for (j=;j<=n;j++)
  21. {
  22. if (p1[j]==&&l1[j]<=i&&r1[j]>=i&&r1[j]<min1)
  23. {
  24. q1=j;
  25. min1=r1[j];
  26. }
  27. if (p2[j]==&&l2[j]<=i&&r2[j]>=i&&r2[j]<min2)
  28. {
  29. q2=j;
  30. min2=r2[j];
  31. }
  32. }
  33. if (q1==-||q2==-)
  34. {
  35. ok=;
  36. break;
  37. }
  38. p1[q1]=i;
  39. p2[q2]=i;
  40. }
  41. if (ok)
  42. for (i=;i<=n;i++)
  43. printf("%d %d\n",p1[i],p2[i]);
  44. else
  45. printf("IMPOSSIBLE\n");
  46. }
  47. }

正解:把按顺序枚举区间变成按顺序枚举点。对于每个点,找到它能放的、右端点最小的区间。

若不取这个区间而取另一个右端点更大的区间,会让之后的点选择变少。

uva 11134 fabled rooks (贪心)——yhx的更多相关文章

  1. 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 t ...

  2. UVA 11134 Fabled Rooks 贪心

    题目链接:UVA - 11134 题意描述:在一个n*n(1<=n<=5000)的棋盘上放置n个车,每个车都只能在给定的一个矩形里放置,使其n个车两两不在同一行和同一列,判断并给出解决方案 ...

  3. UVA 11134 - Fabled Rooks(贪心+优先队列)

    We would like to place  n  rooks, 1 ≤  n  ≤ 5000, on a  n×n  board subject to the following restrict ...

  4. uva 11134 - Fabled Rooks(问题转换+优先队列)

    题目链接:uva 11134 - Fabled Rooks 题目大意:给出n,表示要在n*n的矩阵上放置n个车,并且保证第i辆车在第i个区间上,每个区间给出左上角和右小角的坐标.另要求任意两个车之间不 ...

  5. UVa 11134 - Fabled Rooks 优先队列,贪心 难度: 0

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  6. UVa 11134 Fabled Rooks(贪心)

    题目链接  题意  在n*n的棋盘上的n个指定区间上各放1个'车’ , 使他们相互不攻击(不在同行或同列),输出一种可能的方法. 分析 每行每列都必须放车,把行列分开看,若行和列同时有解,则问题有解. ...

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

    题目链接: https://cn.vjudge.net/problem/UVA-11134 /* 问题 输入棋盘的规模和车的数量n(1=<n<=5000),接着输入n辆车的所能在的矩阵的范 ...

  8. UVa 11134 Fabled Rooks (贪心+问题分解)

    题意:在一个n*n的棋盘上放n个车,让它们不互相攻击,并且第i辆车在给定的小矩形内. 析:说实话,一看这个题真是没思路,后来看了分析,原来这个列和行是没有任何关系的,我们可以分开看, 把它变成两个一维 ...

  9. UVA - 11134 Fabled Rooks问题分解,贪心

    题目:点击打开题目链接 思路:为了满足所有的车不能相互攻击,就要保证所有的车不同行不同列,于是可以发现,行与列是无关的,因此题目可以拆解为两个一维问题,即在区间[1-n]之间选择n个不同的整数,使得第 ...

随机推荐

  1. Dynamics AX 中重点数据源方法

     数据源方法 描述   Active  当用户刚选中一行数据时执行该方法.若选中的是主表的数据,也用该方法来触发加载从表符合条件的数据.主要覆盖该方法来根据条件设置记录及其字段是否可见或是否可被编辑. ...

  2. 在Eclipse中配置Tomcat时,出现Cannot create a server using the selected type错误

    在eclipse中配置Tomcat时,出现Cannot create a server using the selected type错误 原因:Tomcat被删除或者是重新安装,并且安装目录改变了. ...

  3. 状态压缩DP---Hie with the Pie

    http: //acm.hust.edu.cn/vjudge/contest/view.action?cid=110044#problem/B Description The Pizazz Pizze ...

  4. AngularJs Cookie 的使用

    最新在学习 AngularJs ,发现网上很难搜到 AngularJs.Cookie 教程, 就自己写篇博客,希望能帮到刚学的人. 废话不多说上代码 首先要引用 angular-cookies.js ...

  5. [js开源组件开发]js轮播图片支持手机滑动切换

    js轮播图片支持手机滑动切换 carousel-image 轮播图片,支持触摸滑动. 例子见DEMO http://www.lovewebgames.com/jsmodule/carousel-ima ...

  6. 高精度练习(hdoj1042)

    Problem Description Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!   Input One N in ...

  7. 【读书笔记】iOS网络-HTTP-URL百分号编码

    代码: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, ty ...

  8. IOS 杂笔-5(NSTimer极浅析)

    1.timer都会对它的target进行retain,我们需要小心对待这个target的生命周期问题,尤其是重复性的timer. 2. timer不是一种实时的机制,会存在延迟,而且延迟的程度跟当前线 ...

  9. 【转】从viewController讲到强制横屏,附IOS5强制横屏的有效办法

    文字罗嗦,篇幅较长,只需营养可直接看红字部分. 一个viewController的初始化大概涉及到如下几个方法的调用: initWithNibName:bundle: viewDidLoad view ...

  10. UnityShader之Shader分类篇【Shader资料2】

    关于ShaderLab,从我个人的理解上来看应该是分为三种类型. 1.Fixed function shader 固定渲染管线Shader,基于用于高级Shader在老显卡无法显示时的Fallback ...