题解【CF1472E】Correct Placement

题面

2021 第一篇 blog(

临近期末考试,也算是恢复自己竞赛状态的一道题吧。


题意:

对于每一个 (i),找到是否存在一个 (j) 满足 (h_j < h_i & w_j < w_i)(w_j < h_i & h_j < w_i),存在输出任意一个满足条件的 (j),否则输出 -1

对于第一个条件,直接排序扫一遍记录前缀最小值及其编号即可。

第二个条件直接交换 (h_i)(w_i),然后扫一遍即可,思路类似。

具体实现细节与理解参考代码。

#include <bits/stdc++.h>
#define DEBUG fprintf(stderr, "Passing [%s] line %d
", __FUNCTION__, __LINE__)
#define File(x) freopen(x".in","r",stdin); freopen(x".out","w",stdout)
#define DC int T = gi <int> (); while (T--)

using namespace std;

typedef long long LL;
typedef pair <int, int> PII;
typedef pair <int, PII> PIII;

template <typename T>
inline T gi()
{
    T f = 1, x = 0; char c = getchar();
    while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return f * x;
}

const int INF = 0x3f3f3f3f, N = 200003, M = N << 1;

int n;
struct Node
{
	int h, w, id;
} a[N], b[N];
int ans[N];

inline bool cmp(Node x, Node y)
{
	if (x.h != y.h) return x.h < y.h;
	return x.w < y.w;
}

int main()
{
    //File("");
    DC
    {
    	n = gi <int> ();
    	for (int i = 1; i <= n; i+=1)
    		a[i].h = gi <int> (), a[i].w = gi <int> (), a[i].id = i,
    		b[i].h = a[i].w, b[i].w = a[i].h, b[i].id = i;
    	memset(ans, -1, sizeof ans);
    	sort(a + 1, a + 1 + n, cmp);
    	int mn = INF, id = 0;
    	int now = 0;
    	for (int i = 2; i <= n; i+=1)
    		if (a[i].h != a[1].h) {now = i; break;}
    	mn = a[1].w, id = a[1].id;
    	if (now != 0)
    	{
    		int lsmn = INF, lsid = 0;
	    	for (int i = now; i <= n; i+=1)
	    	{
	    		if (a[i].h != a[i - 1].h)
	    		{
	    			if (lsmn < mn) mn = lsmn, id = lsid;
	    			lsmn = a[i].w, lsid = a[i].id;
	    			if (a[i].w > mn) ans[a[i].id] = id;
	    		}
	    		else 
	    		{
	    			if (a[i].w > mn) ans[a[i].id] = id;
	    		}
	    	}
    	}
    	sort(b + 1, b + 1 + n, cmp);
    	int j = 1;
    	mn = INF, id = 0;
    	int cmn = INF, cid = 0;
    	for (int i = 1; i <= n; i+=1)
    	{
    		while (j <= n && b[j].h < a[i].h)
    		{
    			if (b[j].w <= mn)
    				cmn = mn, cid = id, mn = b[j].w, id = b[j].id;
    			else if (b[j].w < cmn)
    				cmn = b[j].w, cid = b[j].id;
    			++j;
    		}
    		if (ans[a[i].id] != -1) continue;
    		if (a[i].w > mn && id != a[i].id)
    			ans[a[i].id] = id;
    		else if (a[i].w > cmn && cid != a[i].id)
    			ans[a[i].id] = cid;
    	}
    	for (int i = 1; i <= n; i+=1) printf("%d ", ans[i]);
    	puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xsl19/p/14287442.html