【LOJ6410】「ICPC World Finals 2018」单割故障

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/88739502

【题目链接】

【思路要点】

  • 不难发现连接两个对角附近的一对点即可构造一组合法解,因此答案应不超过 2 2 ,我们只需判断答案是否可能是 1 1
  • 考虑矩形内两条线段相交的条件,将矩形看做一个环,线段看做一个区间,那么两条线段相交的充要条件为这两条线段对应的区间存在公共部分,但不存在包含关系。
  • 因此,我们需要找到环上的一个区间,使得其包含所有线段的恰好一个端点。
  • 注意到这样的区间内一定有恰好 N N 个端点,枚举即可。
  • 需要排序,时间复杂度 O ( N L o g N ) O(NLogN)

【代码】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e6 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); } 
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
int n, w, h, tot, overall, cnt[MAXN];
pair <int, int> a[MAXN];
int getpos(int x, int y) {
	if (y == 0) return x;
	if (x == w) return w + y;
	if (y == h) return 2 * w + h - x;
	if (x == 0) return 2 * w + 2 * h - y;
	assert(false); return -1;
}
void print(double pos) {
	if (pos <= w) printf("%.1lf %d ", pos, 0);
	else if (pos <= w + h) printf("%d %.1lf ", w, pos - w);
	else if (pos <= 2 * w + h) printf("%.1lf %d ", 2 * w + h - pos, h);
	else printf("%d %.1lf ", 0, 2 * w + 2 * h - pos);
}
int main() {
	read(n), read(w), read(h);
	for (int i = 1; i <= n; i++) {
		int x, y;
		read(x), read(y);
		a[++tot] = make_pair(getpos(x, y), i);
		read(x), read(y);
		a[++tot] = make_pair(getpos(x, y), i);
	}
	sort(a + 1, a + tot + 1);
	for (int i = 1; i <= n; i++)
		if (++cnt[a[i].second] == 1) overall++;
	for (int i = n + 1; i <= tot; i++) {
		if (++cnt[a[i].second] == 1) overall++;
		if (--cnt[a[i - n].second] == 0) overall--;
		if (overall == n) {
			printf("%d\n", 1);
			print(a[i - n].first + 0.5), print(a[i].first + 0.5), putchar('\n');
			return 0;
		}
	}
	printf("%d\n", 2);
	print(0.5), print(w + h + 0.5), putchar('\n');
	print(w + 0.5), print(2 * w + h + 0.5), putchar('\n');
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39972971/article/details/88739502