问题来源:刘汝佳《算法竞赛入门经典--训练指南》 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

代码实现:

 #include "stdio.h"
#include "string.h"
#include "algorithm"
using namespace std; #define N 5010 typedef struct
{
int id;
int l,r;
}Point; int n;
bool mark[N];
Point x[N],y[N],ans[N];
Point ansx[N],ansy[N]; bool cmp(Point a,Point b) { return a.r < b.r; } //按右端点最小的进行排序 bool cmp1(Point a,Point b){ return a.id < b.id;} //按id号还原顺序 bool solve(Point *a,Point *ans)
{
int i,j;
memset(mark,false,sizeof(mark));
for(i=; i<n; i++)
{
for(j=a[i].l; j<=a[i].r; j++)
{
if(mark[j]) continue;
break;
}
if(j>a[i].r) return false;
ans[i].l = j; //用ans[i].l保存答案
ans[i].id = a[i].id;
mark[j] = true;
}
return true;
} int main()
{
int i;
while(~scanf("%d",&n),n!=)
{
for(i=; i<n; i++)
{
scanf("%d %d %d %d",&x[i].l,&y[i].l,&x[i].r,&y[i].r);
x[i].id = y[i].id = i;
}
sort(x,x+n,cmp);
sort(y,y+n,cmp);
if(solve(x,ansx) && solve(y,ansy))
{
sort(ansx,ansx+n,cmp1);
sort(ansy,ansy+n,cmp1);
for(i=; i<n; i++)
printf("%d %d\n",ansx[i].l,ansy[i].l);
}
else
printf("IMPOSSIBLE\n");
}
return ;
}

最新文章

  1. 解决ntp的错误:no server can be used,exiting
  2. SpringBoot相关
  3. laravel5.2 移植到新服务器上除了“/”路由 ,其它路由对应的页面显示报404错误(Object not found!)———新装的LAMP没有加载Rewrite模块
  4. php curl 提交 总结
  5. HDU3232 Crossing rivers
  6. 原生js显示分页效果
  7. Sambar,实现Linux和Windows共享
  8. hdu 4662
  9. Android最佳实践指南
  10. POJ1661 Help Jimmy
  11. jdk1.7 JDBC连接SQL Server2008
  12. CentOS6.5 搭建基础PHP环境(yum安装)
  13. 如何用webgl(three.js)搭建一个3D库房-第一课
  14. ES6 函数的扩展1
  15. EBS开发技术之Patch安装
  16. 转:centos 7 安装音频视频解码器
  17. Java框架spring Boot学习笔记(一):开始第一个项目
  18. TCP网络协议通信原理(客户端和服务器端)
  19. python中获取执行脚本路径方法
  20. vim中文手册

热门文章

  1. 重构第20天 提取子类(Extact SubClass)
  2. 【EF 译文系列】重试执行策略的局限性(EF 版本至少为 6)
  3. 缺少google api密钥,因此chromium的部分功能将无法使用&rdquo;的解决办法
  4. 数据库sqlserver2008登陆名密码登陆不了怎么办?
  5. cURL和HTTPie
  6. java注释指导手册
  7. jquery.cookie.js 用法
  8. c++之函数重载(函数匹配)
  9. 简单封装cookie操作
  10. Automapper扩展方法