Correct Placement
题意
n n n 个矩形 对于每个矩形可以将它横着放或者竖着放 问能否找到另一个矩形能够放在它前面并且不将其遮挡 如果有的话输出符合条件的矩形的编号 否则输出 − 1 -1 −1
翻译成数学表达式即 :对于 a i , b i ( 1 ≤ i ≤ n ) a_i,b_i\ \ \ \ \ (1 \leq i \leq n) ai,bi (1≤i≤n) 能否找到 a j , b j ( 1 ≤ j ≤ n ) a_j,b_j \ \ \ \ (1 \leq j \leq n) aj,bj (1≤j≤n) 使得 ( a i > a j & & b i > b j ) ∣ ∣ ( a i > b j & & b i > a j ) (a_i > a_j \ \ \&\& \ \ b_i > b_j) \ \ || \ \ (a_i > b_j \ \ \&\& \ \ b_i > a_j) (ai>aj && bi>bj) ∣∣ (ai>bj && bi>aj)
思路
首先 将所有矩形的较小值当成宽 较大值当作长 然后对宽进行升序排列 这样排在当前矩形前面的所有矩形的宽都是符合要求的 用 mi 记录 前面所有矩形 长的最小值 如果当前矩形的长大于这个最小值 说明可以在前面找到一个符合条件的矩形
但是会出现这样的一个问题 比如排序后是 1 3 2 2 2 4 2 5 对于第三个和第四个矩形输出 2 2 因为长的最小值更新到了第二个矩形 但是并不符合题意 所以 我们在按宽 递增排序的基础上 让长递减排序 就可以避免这种情况 1 3 2 5 2 4 2 3
代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define mod 1000000007
#define endl '\n'
using namespace std;
typedef long long LL;
typedef pair<int, int>PII;
inline LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; }
const int N = 200010;
int n, x, y;
int ans[N];
struct Node {
int w, l, idx;
}node[N];
bool cmp(Node a, Node b) {
if (a.w != b.w)return a.w < b.w;
else return a.l > b.l;
}
void solve() {
cin >> n;
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &x, &y);
if (x > y)swap(x, y);
node[i].w = x; //宽
node[i].l = y; //长
node[i].idx = i;
}
sort(node + 1, node + 1 + n, cmp);
int mi = node[1].l; //区间最小值
int id = node[1].idx; //最小值的下标
for (int i = 1; i <= n; ++i) {
if (node[i].l <= mi) { //不符合条件
ans[node[i].idx] = -1;
mi = node[i].l;
id = node[i].idx;
}
else {
ans[node[i].idx] = id;
}
}
for (int i = 1; i <= n; ++i) {
if (i == ans[i])printf("-1 ");
else printf("%d ", ans[i]);
}
cout << endl;
}
int main() {
int t; cin >> t;
while(t--)
solve();
return 0;
}