这题刚开始做计算几何的时候就做到了,无奈有点小看不懂,今天又看到这题了,下决心把它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; }