专栏文章

题解:P13396 [GCJ 2010 #1C] Rope Intranet

P13396题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miosj5qy
此快照首次捕获于
2025/12/03 00:26
3 个月前
此快照最后确认于
2025/12/03 00:26
3 个月前
查看原文
要解决本题,我们可以观察到:两根电线会交叉,当且仅当它们的连接方式会交叉
具体地,对于第 ii 根和第 jj 根电线,有如下结论:
  • ai<aja_i<a_jbi>bjb_i>b_j,这两根电线会交叉。
  • ai>aja_i>a_jbi<bjb_i<b_j,这两根电线会交叉。
本质上这就是在计算逆序对的数量。
我们可以通过一下几步解决这个问题:
  • 首先先按左侧建筑物的窗户高度 aia_i 对电线进行排序。这是保证了对于所有 i<ji<j,有 ai<aja_i<a_j
  • 接下来我们根据窗户的新排序就得到了一个新的 bb 序列,这里可以通过结构体排序实现。
  • 根据前面的结论,我们只需要计算满足 i<ji < jbi>bjb_i > b_j 的数对 (i,j)(i,j) 的数量,也就是 bb 序列中逆序对的数量。
其中,由于数据范围很小、时限大,所以逆序对的计算只需要 O(n2)O(n^2) 循环枚举计算即可。
代码如下:
CPP
#include<bits/stdc++.h>
using ll = long long;
using namespace std;

const int N = 1e5 + 5;

struct node {
	int a, b;
} c[N];

bool cmp(const node &x, const node &y) {
	return x.a < y.a;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	
	int q;
	cin >> q;
	
	for (int i = 1; i <= q; i++) {
		int n;
		cin >> n;
		
		for (int i = 1; i <= n; i++) {
			cin >> c[i].a >> c[i].b;
		}
		sort(c + 1, c + n + 1, cmp);
		int cnt = 0;
		for (int i = 1; i <= n; i++) {
			for (int j = i + 1; j <= n; j++) {
				if (c[i].b > c[j].b) cnt++;
			}
		}
		cout << "Case #" << i << ": " << cnt << '\n';
	}
	return 0;
}
省流:我是 Luogu 第 22 个 AC 此题的入。

评论

0 条评论,欢迎与作者交流。

正在加载评论...