zoj 1104 Leaps Tall Buildings(超人不会飞- -。。)

这题刚开始做计算几何的时候就做到了,无奈有点小看不懂,今天又看到这题了,下决心把它A了 = =。。

首先先把顶点全求出来,然后就是抛物线的V和角度与抛物线方程( y = ax^2 + bx + c)的关系。

可知

x = Vx * t;
y = Vy * t - 1/2*g*t*t;

二者联立,消去t,就得到了抛物线方程。

然后我的做法是,二分抛物线二次项系数a,因为已知起点和终点,那么b和a的关系自然有了 -b/(2a) 为极值点 x 坐标,这个x肯定是第一个点和最后一个点的中点x坐标。

然后求出来 a ,b,再由推导出来的关系求出V和角度即可。

我觉得我像是在做高中数学 + 物理混合题。。。T T。。

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")
#define STOP system("pause")

using namespace std;

const int MAX = 110;
const double g = 9.8;
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
bool dy(double x,double y)	{	return x > y + eps;}	// x > y 
bool xy(double x,double y)	{	return x < y - eps;}	// x < y 
bool dyd(double x,double y)	{ 	return x > y - eps;}	// x >= y 
bool xyd(double x,double y)	{	return x < y + eps;} 	// x <= y 
bool dd(double x,double y) 	{	return fabs( x - y ) < eps;}  // x == y
struct point {
    double x,y;
    void p(double xx, double yy)
    {
        x = xx; y = yy;
    }
};
point p[MAX];

double B(double a,double s)
{
    return -2*a*s;
}

int solve(double a, double b, int cnt)
{
    bool flag = false;
    for(int i=1; i<cnt-1; i++)
    {
        double x = p[i].x; 
        double y = p[i].y;
        if( xy(a*x*x + b*x, y) ) return 1;
        if( dd(a*x*x + b*x, y) ) flag = true;
    }
    if( flag ) return 0;
    return -1;
}

int main()
{
    int n;
    double sy, sx;
    while( ~scanf("%d", &n) )
    {
        double ss = 0;
        int cnt = 0;
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf", &sy, &sx);
            p[cnt].x = ss;
            p[cnt++].y = sy;
            p[cnt].x = ss + sx;
            p[cnt++].y = sy;
            ss += sx;
        }
        
        double begin = eps, end = inf;
        
        double s = p[cnt-1].x / 2, b, mid;
        while( begin <= end )
        {
            mid = (begin + end)/2;
            b = B(-mid, s);
            int ans = solve(-mid, b, cnt);
            if( ans == 0 ) break;
            if( ans == 1 )  // 极值点比较低
                begin = mid;
            else
                end = mid;
        }
        
        double ang = atan(b);
        double v = sqrt(g/(2*mid))/cos(ang);
        
        printf("%.2lf %.2lf\n", ang/pi*180, v);
    }
    
return 0;
}


你可能感兴趣的:(c,System)