ZOJ1104-Leaps Tall Buildings

本文介绍了一个编程问题,即如何计算超人飞跃一系列建筑物时所需的最小起始速度与发射角度,以确保其路径上的最高点尽可能地低,同时又能成功越过所有障碍物。通过使用二分查找算法确定最佳跳跃参数。

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

Leaps Tall Buildings

Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge

It's a bird! It's a plane! It's coming right at us!

Although it sometimes seems like it, Superman can't fly (without a plane). Instead, he makes super-human leaps, especially over tall buildings. Since he never knows when he will need to catch a criminal, he can't register flight paths. To avoid hitting planes, he tries to keep his jumps as low to the ground as he can. Given a city-scape as input, find the angle and velocity of Superman's jump that minimizes his maximum altitude.

Recall that gravity provides an acceleration of 9.8 m/s2 downwards and the formula for Superman's vertical distance from his starting location is d(t)=v t + 0.5 a t2 where v is his initial velocity, a is his acceleration and t is time in seconds since the start of the leap.

Input:

Input consists of a sequence of city-scapes, each of the form

n
d1
h2 d2
:
h(n-1) d(n-1)
dn

Superman starts at ground level and leaps d1+...+dn metres, landing at ground level and clearing all of the buildings at heights h2 to h(n-1), each with the given widths. n will be at most 100.

Output:

Output is the angle and initial velocity that minimizes the height that Superman attains, both appearing on the same line. The values should be given to two decimal places and be accurate within 0.01 degrees or m/s, as appropriate.

Sample Input:

3
0 5
10 5
0 5
5
0 10.5
20 11.5
25 10
10 15
0 7

Diagram for Second City-scape

 
(Not to scale.)

Sample Output:

71.57 15.65
67.07 27.16

Source: University of Waterloo Local Contest 1998.06.06


题意:有n个建筑,有一个超人要跳过所有建筑,问最低的高度和初始速度角度

解题思路:二分高度


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>

using namespace std;

#define LL long long
const int INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;

double x[105], y[105];
int n, cnt;
double v, k;

bool check(double h)
{
	double v1 = sqrt(2 * 9.8*h);
	double v2 = x[cnt - 1] / (v1 / 4.9);
	v = sqrt(v1*v1 + v2*v2);
	k = 180 * acos(v2 / v) / pi;
	for (int i = 0; i<cnt; i++)
	{
		double xx;
		if (x[i] > (x[cnt - 1] / 2)) xx = x[cnt - 1] - x[i];
		else xx=x[i];
		double t = xx / v2;
		double hh = v1*t - 4.9*t*t;
		if (hh<y[i]) return 0;
	}
	return 1;
}

int main()
{

	while (~scanf("%d", &n))
	{
		double xx = cnt = 0, a, b;
		for (int i = 1; i <= n; i++)
		{
			scanf("%lf%lf", &a, &b);
			x[cnt] = xx; y[cnt++] = a;
			x[cnt] = xx += b; y[cnt++] = a;
		}
		double l = 0, r =1.0*INF;
		while (r-l>eps)
		{
			double mid = (l + r) / 2;
			if (check(mid)) r = mid;
			else l = mid;
		}
		check(r);
		printf("%lf %lf\n", k, v);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值