题意:
你的任务是在 n*n的棋盘上放n个车,使得任意两个车不相互攻击,且第i个车在一个给定的矩形Ri之内。用四个整数xl,yl,xr,yr 描述矩形,其中前两个点是矩形左上角坐标,后两个点是矩形后两个点坐标,则第i个车的位置(x, y) 必须满足 xl <= x <= xr , yl <= y <= yr 如果无解,输出 “IMPOSSIBLE ” (注意这个impossible后面还有一个空格) 否则输出n行,依次为各个矩形中的车的坐标。
审题:
是不是有点类似八皇后? 然而这个数据规模,一定不是搜索与回溯的,因此不能暴力搜索,因此想到贪心。
这有点类似
区间选点问题的二维状态
对区间选点问题有疑惑的同学,我下面可以简要的介绍一下
比如这个图上,假设我们定义每个区间都是 [a,b]
那么我们可以发现我们需要令 区间从b从小到大排列
然后针对区间长度再进行选择
比如如果b是一样的话,a应该是大的排在前面,想一想为什么?
答案是 因为a既然是大的,b又是一样的,那么上面的区间一定是小的,那么在小的区间里面选择得点,一定覆盖到了大的区间。
因此这题,思路正好反过来
我们应该让选点尽量的不覆盖到每个区间,那怎么做?
我们令b从小到大排列,针对区间长度进行选择,如果b一样的话,a小的排在前面,这样前面会是大的区间,在大的区间的最左边选点的时候,一定不会影响到第二个区间,也就是,车不会在行或者列互相攻击了。
当然这道题也不一定要考虑区间长度的问题,想一想?为什么?
因为你点总是要放的,就算区间小的放在前面,例如针对 [2,4] [1,4]
这样的两个区间 [2,4] 放在前面 也只会在2-4里挑一个位置放车,[1,4] 中总有这个1可以放。但是建议使用前面的方法
测试表明前面的方法时间是 0ms 而无视这一点 时间是 10ms
由于这道题是二维的,所以x和y各做一遍就可以了。
代码如下。
代码的 xd, yd 显然有些多余,简化代码留给读者。
#include<bits/stdc++.h>
#define LL long long
#define ms(s) memset(s, 0, sizeof(s))
using namespace std;
const int maxn = 5000 + 100;
struct rect {
int lx, ly; // 左上角
int rx, ry; // 右下角
int xd, yd;
int posx, posy; // 记录一下这个矩形里面如何放
int id;
}r[maxn];
bool cmp1(rect& r1, rect& r2) {
return r1.rx == r2.