【BZOJ4723】【POI2017】Flappy Bird

【题目链接】

  • 点击打开链接

【思路要点】

  • 首先,横纵坐标奇偶性不同的位置是小鸟无法到达的。
  • 然后,我们旋转坐标系,使得可到达的坐标\((x,y)\)变为\((x,\frac{x+y}{2})\)。
  • 如此,点击屏幕的结果是\((x+1,y+1)\),不点屏幕的结果是\((x+1,y)\)。
  • 维护一个可行的纵坐标区间,贪心即可。
  • 时间复杂度\(O(N)\)。

【代码】

#include
using namespace std;
const int MAXN = 500005;
template  void chkmax(T &x, T y) {x = max(x, y); }
template  void chkmin(T &x, T y) {x = min(x, y); } 
template  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  void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template  void writeln(T x) {
	write(x);
	puts("");
}
int n, m, x[MAXN], l[MAXN], r[MAXN];
int main() {
	read(n), read(m);
	for (int i = 1; i <= n; i++) {
		read(x[i]), read(l[i]), read(r[i]);
		if (l[i] + x[i] == -1) l[i] = 0;
		else l[i] = (l[i] + x[i]) / 2 + 1;
		if (r[i] - 1 + x[i] == -1) r[i] = -1;
		else r[i] = (r[i] - 1 + x[i]) / 2;
		if (l[i] > r[i]) {
			puts("NIE");
			return 0;
		}
	}
	int nl = 0, nr = 0, last = 0;
	for (int i = 1; i <= n; i++) {
		nr += x[i] - last;
		last = x[i];
		chkmax(nl, l[i]);
		chkmin(nr, r[i]);
		if (nl > nr) {
			puts("NIE");
			return 0;
		}
	}
	printf("%d\n", nl);
	return 0;
}

你可能感兴趣的:(【OJ】BZOJ,【类型】做题记录,【算法】贪心,【资料】好题,【算法】旋转坐标系)