E. Correct Placement - Codeforces Round #693
阿新 • • 發佈:2021-01-07
Correct Placement
題目連結:https://codeforces.com/contest/1472/problem/E
題目大意
\(n\) 個人,每個人有高 \(h\) 和寬 \(w\) 兩個屬性。第 \(j\) 個人能站在第 \(i\) 個人前面當且僅當 \(h_j < h_i and w_j < w_i\) 或 \(w_j < h_i and h_j < w_i\)。
解題思路
因為每個人既能豎著也能橫著放,我們直接把大的值當 \(h\) ,小的當 \(w\) ,方便後面處理。
然後我們把 \(n\) 個人按身高從小到大排序,那麼對於我們當前列舉的人 \(i\)
注意 \(i\) 前面可能存在身高等於 \(h_i\) 的,找 \(w_{min}\) 的時候不能算上這些人。
Code
#include <cstdio> #include <algorithm> #include <cstring> #define MAXN 200005 using namespace std; struct node { int h, w; int id; } a[MAXN]; int ans[MAXN]; bool cmp1(node& t1, node& t2) { if(t1.h == t2.h) return t1.w < t2.w; else return t1.h < t2.h; } int main(void) { int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); for(int i=0;i<n;++i) { int h, w; scanf("%d%d", &h, &w); if(h < w) swap(h, w); a[i].h = h; a[i].w = w; a[i].id = i+1; } sort(a, a+n, cmp1); memset(ans, -1, (n+1) * sizeof(int)); int p = 0; int minw = 1e9, mink = -1; for(int i=0;i<n;++i) { if(i > 0 && a[i].h > a[i-1].h) { while(p < i) { // p 到 i-1 的 h 是相等的 if(a[p].w < minw) { minw = a[p].w; mink = a[p].id; } p++; } } if(minw >= a[i].w) ans[a[i].id] = -1; else ans[a[i].id] = mink; } for(int i=1;i<=n;++i) printf("%d ", ans[i]); printf("\n"); } return 0; }