SCAU 18112 Play Ball

SCAU 18112 Play Ball

时间限制:1000MS 内存限制:65535K
提交次数:0 通过次数:0

题型: 编程题 语言: 不限定
Description
One day, Xiaoming and his friends want to play the basketball, but there are not basketball court nearby. So they
come out with a new idea to play game. At the beginning, Xiaoming hold the ball, and he throw the ball to one of his
friends, and his friend receive the ball and throw it to another one, until some one can throw it to the target(just
a point).
To simplify the game, we just consider the people is a point, and the target is a point as well. They all(include
the target) in the same horizontal plane and can’t move. Every one can and only can throw the ball with the speed vi
in arbitrary direction. While the ball touches the earth(the horizontal plane) before someone receive it, it stops and
stays at that point, which means the game is over.
Give the position (xi, yi) of all people and the target, and the initial speed vi (m/s) of ball. we consider the acceleration
of gravity is 10 (m/(s^2)). You should tell me the minimum time (t) to throw the ball to target.
What’s more, it always has solution.

输入格式

The input file begins with an integer T (T <= 20) in one row indicating the number of test case. Then T test cases follows.
First row is xiaoming's position x, y, and the ball speed v.

Second row is n, the number of xiaoming’s friends .
next n row is xiaoming’s friends’ position xi, yi and the ball speed vi. last row is target’s position xt, yt (n <= 10, the
absolute of other value is less than 100)

输出格式
For each case, print an real number with exactly 3 decimal places .

输入样例
1
0 0 8
0
3 3

输出样例
0.567

网上找不到题解,来发一个吧~
这是一道物理加最短路。

两点时间计算公式:t=2vsin(asin(10x/(vv))/2)/10;
算出时间之后,两点的时间就是两点的权值,然后用迪杰斯特拉算法求起点到终点的最短时间。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#define MAXN 0x7fffffff^ - ^

using namespace std;

struct stu {
    
    double x,y,v;}s[20];          			///这里用0~n+1的结构体保存坐标,速度
int main()
{
    
    
    int n,i,j,k,m,l,T,v[15];
    double t[15][15],dis[15];
    cin >> T ;
    while(T--)
    {
    
    
        memset(v,0,sizeof(v));       					 ///初始化
        for(i=0;i<15;++i)dis[i]=MAXN;
        for(i=0;i<15;++i)for(j=0;j<15;++j)t[i][j]=MAXN;
        for(i=0;i<20;++i)s[i].x=s[i].y=s[i].v=0;
        scanf("%lf%lf%lf",&s[0].x,&s[0].y,&s[0].v);
        scanf("%d",&n);
        for(i=1;i<=n;++i)
            scanf("%lf%lf%lf",&s[i].x,&s[i].y,&s[i].v);
        //scanf("%lf%lf",&s[n+1].x,&s[n+1].y);
        for(i=0;i<=n;++i)									///预处理时间
            for(j=0;j<=n+1;++j){
    
    
                if(i==j)continue;
                double x=(double)sqrt( pow(s[i].x-s[j].x,2)+pow(s[i].y-s[j].y,2) );
                if(2*s[i].v*sin(asin(10*x/(s[i].v*s[i].v))/2)/10>0)
                    t[i][j]=2*s[i].v*sin(asin(10*x/(s[i].v*s[i].v))/2)/10;
            }
        dis[0]=0;v[0]=1;									///预处理初始能到起点的点的距离
        for(i=1;i<=n+1;++i){
    
    
            if(t[0][i]<MAXN)dis[i]=t[0][i];
        }
        for(i=1;i<=n+1;++i){
    
    								///跑最短路
            double minn=MAXN;
            int vv=-1;
            for(j=0;j<=n+1;++j)							///找一个距离起点最近的并且没有标记的点
                if(!v[j]&&minn>dis[j]){
    
    
                    vv=j;
                    minn=dis[j];
                }
            if(vv!=-1){
    
    											///找到了就标记一下
                for(v[vv]=1,j=0;j<=n+1;++j)			///替换中。。。
                    if(!v[j]&&dis[j]>t[vv][j]+dis[vv]){
    
    
                        dis[j]=t[vv][j]+dis[vv];
                        t[0][j]=dis[j];
                    }
            }
        }
        printf("%.3f\n",dis[n+1]);
    }
    ^ - ^
}

猜你喜欢

转载自blog.csdn.net/m0_45699242/article/details/104862289