CodeForces - 1472E- Correct Placement (排序 + 思维)

12 篇文章 0 订阅
2 篇文章 0 订阅

Correct Placement

题意

n n n 个矩形 对于每个矩形可以将它横着放或者竖着放 问能否找到另一个矩形能够放在它前面并且不将其遮挡 如果有的话输出符合条件的矩形的编号 否则输出 − 1 -1 1

翻译成数学表达式即 :对于 a i , b i       ( 1 ≤ i ≤ n ) a_i,b_i\ \ \ \ \ (1 \leq i \leq n) ai,bi     (1in) 能否找到 a j , b j      ( 1 ≤ j ≤ n ) a_j,b_j \ \ \ \ (1 \leq j \leq n) aj,bj    (1jn) 使得 ( a i > a j    & &    b i > b j )    ∣ ∣    ( a i > b j    & &    b i > a j ) (a_i > a_j \ \ \&\& \ \ b_i > b_j) \ \ || \ \ (a_i > b_j \ \ \&\& \ \ b_i > a_j) (ai>aj  &&  bi>bj)    (ai>bj  &&  bi>aj)

思路

首先 将所有矩形的较小值当成宽 较大值当作长 然后对宽进行升序排列 这样排在当前矩形前面的所有矩形的宽都是符合要求的 用 mi 记录 前面所有矩形 长的最小值 如果当前矩形的长大于这个最小值 说明可以在前面找到一个符合条件的矩形

但是会出现这样的一个问题 比如排序后是 1 3 2 2 2 4 2 5 对于第三个和第四个矩形输出 2 2 因为长的最小值更新到了第二个矩形 但是并不符合题意 所以 我们在按宽 递增排序的基础上 让长递减排序 就可以避免这种情况 1 3 2 5 2 4 2 3

代码

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define mod 1000000007
#define endl '\n'
using namespace std;

typedef  long long LL;
typedef pair<int, int>PII;
inline LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; }
const int N = 200010;

int n, x, y;
int ans[N];

struct Node {
	int w, l, idx;
}node[N];

bool cmp(Node a, Node b) {
	if (a.w != b.w)return a.w < b.w;
	else return a.l > b.l;
}

void solve() {
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		scanf("%d%d", &x, &y);
		if (x > y)swap(x, y);
		node[i].w = x; //宽
		node[i].l = y; //长
		node[i].idx = i;
	}
	
	sort(node + 1, node + 1 + n, cmp);

	int mi = node[1].l; //区间最小值
	int id = node[1].idx; //最小值的下标
	
	for (int i = 1; i <= n; ++i) {
		if (node[i].l <= mi) { //不符合条件
			ans[node[i].idx] = -1;
			mi = node[i].l;
			id = node[i].idx;
		}
		else {
			ans[node[i].idx] = id;
		}
	}

	for (int i = 1; i <= n; ++i) {
		if (i == ans[i])printf("-1 ");
		else printf("%d ", ans[i]);
	}
	cout << endl;
}

int main() {
	int t; cin >> t;
	while(t--)
		solve();

	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zzqwtc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值