箭头识别

该问题描述了一个关于在平面上寻找由三个点构成的最大箭头的条件。箭头必须满足特定的坐标顺序和长度、宽度比例。给定平面内的N个点,任务是找到能构成的最大箭头的尺寸。输入包含测试用例数量T和每个用例的点坐标,输出每个用例的最大箭头尺寸。当不存在箭头时,尺寸为-1。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TimeLimit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K(Java/Other)

Problem Description

Three pointsA(x1,y1), B(x2,y2) and C(x3,y3) form a arrow if and only if the followingconditions are fulfilled:
x1=x3<x2
y1<y2<y3
The length of the arrow(x2-x1) must not shorter than the width of the arrowy3-y1.
We define the size of an arrow as its length plus its width. Given N points inthe plane, what's the largest possible arrow can be formed from three of thegiven points.

Input

The first line ofthe input contains a positive integer T<=20 specifying the number of testcases to follow.
the first line of each test case contains a positive integerN(1<=N<=2000). Then follow N lines, each describes a point withcoodinates(xi,yi)(0<=xi,yi<=10^7).
It's assumed that no two points are at the same location.

Output

For each test caseyou should output a single line containing "Case X: Y"(quotes forclarity) where X is the number of the test case(starting at 1). Y is the sizeof the largest arrow in the plane. If there's not any arrow in the plane, Yshould be equal to -1.

Sample Input

1
5
2 2
2 5
6 4
2 4
2 10

Sample Output

Case 1: 7

标程:

#include <cstdio>
#include <algorithm>
#include <set>
#include <cassert>
using namespace std;
#define maxn 2010

int Y[maxn];
int px[maxn], py[maxn];
int yy[maxn];
int f[maxn];
int id[maxn];

bool cmp(int a, int b) {
	if (px[a] != px[b]) return px[a] < px[b];
	return py[a] < py[b];
}

int mylog[maxn];
int rmq[11][maxn];

void prepare(int n) {
	int i, j, k;
	for(i = 0; i <= n; mylog[i++] = k)
		for(k = 0; (1 << (k + 1)) < i; k++);
	for(j = 0; (1 << j) <= n; j++)
		for(i = 0; i + (1<<j) <= n; i++){
			if(j == 0) rmq[j][i] = f[i];
			else rmq[j][i] =
				max(rmq[j - 1][i], rmq[j - 1][i + (1 << (j - 1))]);
		}
}

int query(int i, int j) {
	int k = mylog[j - i + 1];
	return max(rmq[k][i], rmq[k][j - (1 << k) + 1]);
}
set< pair<int, int> >SET;
int main() {
	int t;
	//freopen("arrow.in", "r", stdin);
	//freopen("arrow.out", "w", stdout);
	assert(scanf("%d", &t) == 1);
	assert(1 <= t && t <= 20);
	for (int kase = 1; kase <= t; ++kase) {
		int n, ycnt = 0;
		assert(scanf("%d", &n) == 1);
		assert(1 <= n && n <= 2000);
		SET.clear();
		for (int i = 0; i < n; ++i) {
			assert(scanf("%d%d", &px[i], &py[i]) == 2);
			assert(0 <= px[i] && px[i] <= 10000000 &&
					0 <= py[i] && py[i] <= 10000000);
			assert(SET.find(make_pair(px[i], py[i])) == SET.end());
			SET.insert(make_pair(px[i], py[i]));
			Y[ycnt++] = py[i];
			id[i] = i;
		}
		sort(Y, Y + ycnt);
		ycnt = unique(Y, Y + ycnt) - Y;

		for (int i = 0; i < ycnt; ++i) {
			f[i] = 0;
		}

		for (int i = 0; i < n; ++i) {
			int id = lower_bound(Y, Y + ycnt, py[i]) - Y;
			if (f[id] < px[i]) f[id] = px[i];
		}
		prepare(ycnt - 1);
		int ans = -1;

		sort(id, id + n, cmp);
		for (int i = 0; i < n; ++i) {
			yy[i] = lower_bound(Y, Y + ycnt, py[id[i]]) - Y;
		}
		for (int i = 0; i < n; ++i) {
			for (int j = i + 1; j < n; ++j) {
				if (px[id[j]] != px[id[i]]) break;
				int width = py[id[j]] - py[id[i]];
				if (width < 2) continue;
				int length = query(yy[i] + 1, yy[j] - 1) - px[id[i]];
				if (length >= width &&
						width + length > ans) ans = width + length;
			}
		}
		printf("Case %d: %d\n", kase, ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值