E. Correct Placement (thinking + greedy + two-dimensional partial order)

https://codeforces.com/problemset/problem/1472/E


Question: There are n wi*hi squares, and then they can be placed horizontally or vertically. Ask who is placed in front of each square without being blocked. The definition of not being blocked is that the length and width of the front square are smaller than those of the back square.

Ideas:

Converted into mathematics is ai>aj&&bi>bj || ai>bj&&bi>aj

Two practices:

Since the first condition is hi>hj&&wi>wj, the second condition is hi>wi&&wj>hj

It can be found that the upper left is the form of the second condition, but when we take the long as w and the short as h, the transformed figure is the first condition. Unified into one condition.

It can be simulated.

A detail of greed: Note that when the first dimension is the same, the second dimension is first arranged in the larger order.

w  2   3   3 

h 3 2 4 This update results in the small value of h that cannot be updated to the third one.

Replace with

w 2 3 3

h 3 4 2 is fine

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
struct P{
    LL h,w,id;
}a[maxn];
LL pre[maxn];
vector<LL>v[maxn];
bool cmp(P A,P B){
    if(A.w==B.w) return A.h>B.h;///要反过来
    return A.w<B.w;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL t;cin>>t;
  while(t--){
    LL n;cin>>n;
    for(LL i=0;i<n+10;i++) v[i].clear();
    for(LL i=1;i<=n;i++){
        LL h,w;cin>>h>>w;
        a[i].h=max(h,w);
        a[i].w=min(h,w);
        a[i].id=i;
    }
    sort(a+1,a+1+n,cmp);

    v[a[1].id].push_back({-1});
    LL pos=a[1].id;
    LL pre=a[1].h;
    LL width=a[1].w;

    for(LL i=2;i<=n;i++){
        if(a[i].h>pre&&a[i].w>width){
            v[a[i].id].push_back({pos});
        }
        else v[a[i].id].push_back({-1});
        if(pre>a[i].h){
            pos=a[i].id;
            width=a[i].w;
            pre=a[i].h;
        }
    }

    for(LL i=1;i<=n;i++){
        cout<<v[i][0]<<" ";
    }
    cout<<"\n";
  }
return 0;
}

The second idea;

Similar to the demolition point, the demolition numbers are the same.

The two lengths and widths of each point are assigned respectively to form a point, which is put into order, so that the two states are compared in it.

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
struct P{
   LL h,w,id;
}a[maxn*2];
LL tot=0;
vector<LL>v[maxn];
bool cmp(P A,P B){
    if(A.h==B.h) return A.w>B.w;
    return A.h<B.h;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL t;cin>>t;
  while(t--){
    LL n;cin>>n;
    tot=0;
    for(LL i=0;i<n*2+10;i++) v[i].clear();
    for(LL i=1;i<=n;i++){
        LL h,w;cin>>h>>w;
        a[++tot].h=h;a[tot].w=w;a[tot].id=i;
        a[++tot].h=w;a[tot].w=h;a[tot].id=i;
    }
    sort(a+1,a+1+tot,cmp);
    v[a[1].id].push_back({-1});

    LL pos=a[1].id;
    LL minw=a[1].w;
    LL minh=a[1].h;

    for(LL i=2;i<=tot;i++){
        if(a[i].h>minh&&a[i].w>minw){
            v[a[i].id].push_back({pos});
        }
        if(minw>a[i].w){
            minw=a[i].w;
            minh=a[i].h;
            pos=a[i].id;
        }
    }
    for(LL i=1;i<=n;i++){
        if(v[i].size()==0) cout<<"-1"<<" ";
        else cout<<v[i][0]<<" ";
    }
    cout<<"\n";
  }
return 0;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/114855003