CodeForces - 1472E Correct Placement(思维)
题意:
给出 n n n个矩形的宽和高,如果满足以下条件之一,则一个矩形能放在另一个矩形前面:
1. w i < w j w_i<w_j wi<wj 并且 h i < h j h_i<h_j hi<hj
2. w i < h j w_i<h_j wi<hj 并且 h i < w j h_i<w_j hi<wj
求每个矩形是否能找到一个矩形放在它的前面,输出编号
题解:
一开始的思路是两个条件分开讨论,但是发现第二个条件并不好求。因此要转换一下思路。
仔细看这两个条件,其实就是 m i n ( w i , h i ) < m i n ( w j , h j ) min(w_i,h_i) <min(w_j,h_j) min(wi,hi)<min(wj,hj) , m a x ( w i , h i ) < m a x ( w j , h j ) max(w_i,h_i) <max(w_j,h_j) max(wi,hi)<max(wj,hj)
那么可以直接把大的放在 w w w,小的放 h h h ,然后按照 w w w 排序,维护前缀最小的 h h h 和其下标即可。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int mod=1e9+7;
const int MAXN=2e5+5;
const int inf=0x3f3f3f3f;
struct node
{
int w,h;
int id;
/* data */
}f[MAXN];
int ans[MAXN];
int p[MAXN];
int dp[MAXN];
bool cmp(node x,node y)
{
return x.w<y.w;
}
int main()
{
//==========================================
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
//==========================================
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>f[i].w>>f[i].h;
if(f[i].w<f[i].h) swap(f[i].w,f[i].h);
f[i].id=i;
}
sort(f+1,f+1+n,cmp);
int pos=-1;
int minn=2e9;
dp[1]=f[1].h;
p[1]=1;
for(int i=2;i<=n;i++)
{
if(f[i].h<dp[i-1])
{
dp[i]=f[i].h;
p[i]=i;
}
else
{
dp[i]=dp[i-1];
p[i]=p[i-1];
}
}
for(int i=1;i<=n;i++)
{
int l=1,r=n;
int pos=-1;
while(l<=r)
{
int mid=(l+r)>>1;
if(f[mid].w<f[i].w)
{
pos=mid;
l=mid+1;
}
else r=mid-1;
}
if(pos==-1) ans[f[i].id]=-1;
else if(dp[pos]>=f[i].h) ans[f[i].id]=-1;
else ans[f[i].id]=f[p[pos]].id;
}
for(int i=1;i<=n;i++)
{
cout<<ans[i]<<" ";
}
cout<<endl;
}
}

浙公网安备 33010602011771号