【题解】Correct Placement【排序】
链接:https://codeforces.com/contest/1472/problem/E
E. Correct Placement
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Polycarp has invited nn friends to celebrate the New Year. During the celebration, he decided to take a group photo of all his friends. Each friend can stand or lie on the side.
Each friend is characterized by two values hi (their height) and wiwi (their width). On the photo the i-th friend will occupy a rectangle hi×wi (if they are standing) or wi×hi (if they are lying on the side).
The j-th friend can be placed in front of the i-th friend on the photo if his rectangle is lower and narrower than the rectangle of the i-th friend. Formally, at least one of the following conditions must be fulfilled:
- hj<hi and wj<wi (both friends are standing or both are lying);
- wj<hi and hj<wi (one of the friends is standing and the other is lying).
For example, if n=3, h=[3,5,3] and w=[4,4,3], then:
- the first friend can be placed in front of the second: w1<h2 and h1<w2 (one of the them is standing and the other one is lying);
- the third friend can be placed in front of the second: h3<h2 and w3<w2 (both friends are standing or both are lying).
In other cases, the person in the foreground will overlap the person in the background.
Help Polycarp for each i find any j, such that the j-th friend can be located in front of the i-th friend (i.e. at least one of the conditions above is fulfilled).
Please note that you do not need to find the arrangement of all people for a group photo. You just need to find for each friend i any other friend j who can be located in front of him. Think about it as you need to solve nn separate independent subproblems.
Input
The first line contains one integer t (1≤t≤1e4) — the number of test cases. Then t test cases follow.
The first line of each test case contains one integer n (1≤n≤2e5) — the number of friends.
This is followed by n lines, each of which contains a description of the corresponding friend. Each friend is described by two integers hi and wi (1≤hi,wi≤1e9) — height and width of the i-th friend, respectively.
It is guaranteed that the sum of n over all test cases does not exceed 2e5.
Output
For each test case output nn integers on a separate line, where the i-th number is the index of a friend that can be placed in front of the i-th. If there is no such friend, then output -1.
If there are several answers, output any.
题目大意:
有n个长方形,可以竖着放也可以横着放。如果一个长方形的水平边小于另一个长方形的水平边,且它的垂直边也小于另一个长方形的垂直边,那么这个长方形可以被放在另一个长方形的前面。已知这n个长方形的长和宽,输出对于每个长方形,哪个长方形可以放在它前面;如果不存在可以放在它前面的长方形,输出-1。
题目分析:
一个长方形可以被放在另一个长方形前面,等价于这个长方形的短边小于另一个长方形的短边,且长边小于另一个长方形的长边。
基于这一点,我们只需记录每个长方形的短边和长边,按照长边从小到大排序。对于排序后的第i个长方形,可能放在它前面的长方形一定在前i-1个长方形中。因为本题只需要找到任意一个可以放在它前面的长方形,所以只需维护前i-1个长方形中短边的最小值,如果这个最小值比它的短边小,那么最小值对应的长方形一定是可行的解,否则不存在可以放在它前面的长方形。
简单来说,本题的解法是:按照长边排序,维护前缀短边的最小值。
需要注意的是,可能有很多长方形长边相等,因为只有当严格小于时才能把长方形放在前面,所以对于长边相等的情况需要进行特判。具体来说,只需要在维护前缀最小值时判断一下长边是否相等就行了。
代码实现:
#include <bits/stdc++.h> using namespace std; const int maxn=2e5+5; int t; int n; struct nn{ int id,begin,end; }node[maxn]; int ans[maxn]; int minx,minid;//到当前end最远的begin int minn,minnid; bool cmp(nn a,nn b){ return a.end<b.end; } int main(){ scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1;i<=n;i++){ int w,h; scanf("%d%d",&w,&h); node[i].id=i; node[i].begin=min(w,h); node[i].end=max(w,h); } sort(node+1,node+1+n,cmp); minx=node[1].begin; minid=node[1].id; ans[node[1].id]=-1; minn=minx; minnid=minid; for(int i=1;i<=n;i++){ if(node[i].end==node[1].end){ ans[node[i].id]=-1; }else if(minx<node[i].begin)ans[node[i].id]=minid; else ans[node[i].id]=-1; if(node[i].begin<minn){ minn=node[i].begin; minnid=node[i].id; } if(node[i].end!=node[i+1].end){ if(minn<minx){ minx=minn; minid=minnid; } minn=node[i+1].begin; minnid=node[i+1].id; } } for(int i=1;i<=n;i++)printf("%d ",ans[i]); printf("\n"); } return 0; }
碎碎念:
初始化不是规范的写法。
因为初始化的原因,debug了八千五百万年QAQ

浙公网安备 33010602011771号