【SCAU 16校赛】 18112 Play Ball 物理 最短路 floyd

32 篇文章 3 订阅
18 篇文章 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

提示
while you throw something out, the acceleration of gravity will always influence it. So you will throw the ball with an angle,
the angle between the horizontal plane.If the angle between the horizontal plane is C, the speed is v, the begining speed on
horizontal direction vx = v * cos©, the begining speed on vertical direction vy = v * sin©.You should never forget the
acceleration of gravity. What’s more, you should not consider air resistance.

In the sample, Xiaoming has no friend, he has to throw the ball to target (3, 3). When he throw the ball by 10.3805°or 

69.2388°, the ball will arrive at the target. And the first one minimize the time, which is 0.567s.

题意:从0号对球做斜抛运动给另外一个人,知道到n+1号点,问最短时间

思路(最短路):

简单的高一物理公式推导+floyd: 1.题意转换:其实就是一个最短路的变型题。只不过现在两点间的边权变成了时间,而这个时间是可以通过 v 和 d(两点间距离)推导出来的。 2.公式推导:斜抛运动等时性, 设Vy为V的竖直方向分速度,Vx为水平方向分速度,那么就有 t = 2*Vy/g 同时 Vx * t = d。 换成V表示就是V²*sin(2a)/g = d , 那么可以通过asin函数解出 角a 大小,然后带回上面t = 2*Vy/g的等式中即可求出t。 这时候的t便是两点间边权 3.最后注意一下上述计算的时候可能产生无解的情况。就是根本不可能在这两点间投掷的。这个时候sin2a解出来会大于1,特判一下即可。 4.然后就跑个floyd即可

AC代码:

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 3e4+2;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };

double dp[20][20];
ll n;

typedef struct Pos
{
    double x;
    double y;
    double v1;
}P;
P a[20];

int main()
{
    int kase;
    cin>>kase;
    while(kase--)
    {
        double x,y,v;
        cin>>x>>y>>v;
        cin>>n;
        rep(i,0,n+1) rep(j,0,n+1) if(i==j) dp[i][j] = 0; else dp[i][j] = (double)inf;
        rep(i,1,n)  cin>>a[i].x>>a[i].y>>a[i].v1;
        double g = 10.0;
        a[0].x = x, a[0].y = y, a[0].v1 = v;
        cin>>a[n+1].x>>a[n+1].y; a[n+1].v1 = (double)inf;
        rep(i,0,n+1) rep(j,0,n+1)
        {
            v = a[i].v1; double d = sqrt( (a[i].x-a[j].x)*(a[i].x-a[j].x) + (a[i].y-a[j].y)*(a[i].y-a[j].y) ) ;
            if(g*d/(v*v)>1) dp[i][j] = (double) inf;
            else
            dp[i][j] =  sin( asin(g*d/(v*v))/2.0 ) * 2 * v / g ;
        }
        rep(k,0,n+1) rep(i,0,n+1) rep(j,0,n+1) dp[i][j] = min(dp[i][k]+dp[k][j],dp[i][j]);
        printf("%.3f\n",dp[0][n+1]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值