1. 程式人生 > 實用技巧 >【題解】Correct Placement【排序】

【題解】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 invitednnfriends 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 valueshi(their height) andwiwi(their width). On the photo thei-th friend will occupy a rectanglehi×wi(if they are standing) orwi×hi(if they are lying on the side).

Thej-th friend can be placed in front of thei-th friend on the photo if his rectangle is lower and narrower than the rectangle of thei-th friend. Formally,at least one

of the following conditions must be fulfilled:

  • hj<hiandwj<wi(both friends are standing or both are lying);
  • wj<hiandhj<wi(one of the friends is standing and the other is lying).

For example, ifn=3,h=[3,5,3]andw=[4,4,3], then:

  • the first friend can be placed in front of the second:w1<h2andh1<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<h2andw3<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 eachifind anyj, such that thej-th friend can be located in front of thei-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 friendiany other friendjwho can be located in front of him. Think about it as you need to solvennseparate independent subproblems.

Input

The first line contains one integert(1≤t≤1e4)— the number of test cases. Thent test cases follow.

The first line of each test case contains one integern(1≤n≤2e5)— the number of friends.

This is followed bynlines, each of which contains a description of the corresponding friend. Each friend is described by two integershiandwi(1≤hi,wi≤1e9)— height and width of thei-th friend, respectively.

It is guaranteed that the sum ofnover all test cases does not exceed2e5.

Output

For each test case outputnnintegers on a separate line, where thei-th number is the index of a friend that can be placed in front of thei-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