【Codeforces 1472 E】Correct Placement,结构排序,二分搜索

problem

E. Correct Placement
time limit per test4 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Polycarp has invited n 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 wi (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 n separate independent subproblems.

Input
The first line contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.

The first line of each test case contains one integer n (1≤n≤2⋅105) — 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≤109) — height and width of the i-th friend, respectively.

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output
For each test case output n 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.

Example
inputCopy
4
3
3 4
5 4
3 3
3
1 3
2 2
3 1
4
2 2
3 1
6 3
5 4
4
2 2
2 3
1 1
4 4
outputCopy
-1 3 -1
-1 -1 -1
-1 -1 2 2
3 3 -1 3
Note
The first test case is described in the statement.

In the third test case, the following answers are also correct:

[−1,−1,1,2];
[−1,−1,1,1];
[−1,−1,2,1].
Let’s sort all people by their height in descending order.

Now let’s

go through all the people and look for the position of the person in the sorted array, the height of which is strictly less than ours (for example, by binary search). Obviously, only those people who are in the sorted array later than the found person can stand in front of us (all of them have a height strictly less than ours).

Among all these people, it is more profitable for us to take a person with minimum width. In order to find such a person quickly, we can find a person with the minimum width for each suffix of the sorted array.

To handle a situation where a person is lying down, we need to swap the width and height and repeat the algorithm above.

solution
/*
题意:
+ 给出n个人的hi和wi,每个人可以站着或躺着
+ 判断对于第i个人,是否存在另一个人可以站在他前面
思路:
+ 直接模拟
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 5e5+10;
const int mod = 1e9+7;
struct node{
	int id, ans; pair<int,int>ww;
}a[maxn];
bool cmp(node a, node b){
	if(a.ww.first!=b.ww.first)return a.ww.first<b.ww.first;
	return a.ww.second>b.ww.second;
}
bool cmp2(node a, node b){
	return a.id<b.id;
}

int main(){
	int T;  cin>>T;
	while(T--){
		int n;  cin>>n;
		for(int i = 1; i <= n; i++){
			a[i].id = i;
			a[i].ans = -1;
			cin>>a[i].ww.first>>a[i].ww.second;
			if(a[i].ww.first<a[i].ww.second)swap(a[i].ww.first,a[i].ww.second);
		}
		sort(a+1,a+n+1,cmp);
		int tmp = 1;
		for(int i = 2; i <= n; i++){
			if(a[i].ww.second>a[tmp].ww.second){
				a[i].ans = a[tmp].id;
			}
			if(a[i].ww.second < a[tmp].ww.second){
				tmp = i;
			}
		}
		sort(a+1,a+n+1,cmp2);//恢复排序
		for(int i = 1; i <= n; i++)
			cout<<a[i].ans<<" ";
		cout<<"\n";
	}
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小哈里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值