[LOJ6410] "ICPC World Finals 2018" single cut fault

[title link]

[main ideas]

  • It is not difficult to find a pair of points connecting two diagonals to construct a combined solution, so the answer should not exceed 222, we only need to judge whether the answer is 111.
  • Considering the condition that two line segments intersect in the rectangle, the rectangle is regarded as a ring and the line segment is regarded as an interval, the necessary and sufficient condition for the intersection of the two line segments is that there is a common part of the interval corresponding to the two line segments, but there is no inclusion relationship.
  • Therefore, we need to find an interval on the ring that contains exactly one endpoint of all the segments.
  • Note that there must be exactly NNN endpoints in such an interval. Enumeration is enough.
  • Sorting is required. Time complexity O(NLogN)O(NLogN)O(NLogN).

[Code]

#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;
}

Posted by The voice on Fri, 06 Dec 2019 23:10:24 -0800