[置顶] 计算几何--bnu51638

Air Hockey

Time Limit: 1000ms
Memory Limit: 262144KB
64-bit integer IO format:  %lld      Java class name:  Main
Special Judge
Prev 
Submit  Status  Statistics  Discuss
  Next
Type: 
None
  None Graph Theory      2-SAT     Articulation/Bridge/Biconnected Component      Cycles/Topological Sorting/Strongly Connected Component      Shortest Path          Bellman Ford         Dijkstra/Floyd Warshall      Euler Trail/Circuit      Heavy-Light Decomposition     Minimum Spanning Tree      Stable Marriage Problem      Trees     Directed Minimum Spanning Tree      Flow/Matching          Graph Matching             Bipartite Matching              Hopcroft–Karp Bipartite Matching              Weighted Bipartite Matching/Hungarian Algorithm          Flow              Max Flow/Min Cut             Min Cost Max Flow  DFS-like      Backtracking with Pruning/Branch and Bound      Basic Recursion     IDA* Search      Parsing/Grammar     Breadth First Search/Depth First Search      Advanced Search Techniques          Binary Search/Bisection         Ternary Search  Geometry      Basic Geometry     Computational Geometry      Convex Hull      Pick's Theorem Game Theory      Green Hackenbush/Colon Principle/Fusion Principle      Nim     Sprague-Grundy Number  Matrix     Gaussian Elimination      Matrix Exponentiation Data Structures      Basic Data Structures     Binary Indexed Tree      Binary Search Tree      Hashing     Orthogonal Range Search      Range Minimum Query/Lowest Common Ancestor      Segment Tree/Interval Tree     Trie Tree      Sorting      Disjoint Set String      Aho Corasick     Knuth-Morris-Pratt      Suffix Array/Suffix Tree Math      Basic Math     Big Integer Arithmetic      Number Theory         Chinese Remainder Theorem          Extended Euclid        nbsp; Inclusion/Exclusion         Modular Arithmetic      Combinatorics          Group Theory/Burnside's lemma         Counting      Probability/Expected Value  Others     Tricky      Hardest     Unusual      Brute Force     Implementation      Constructive Algorithms     Two Pointer      Bitmask     Beginner      Discrete Logarithm/Shank's Baby-step Giant-step Algorithm      Greedy     Divide and Conquer  Dynamic Programming                   Tag it!

无聊的过河船同学和无聊的胀鱼同学非常喜欢打桌上冰球(其实只是喜欢听球碰撞时的声音)。在无聊的一天,无聊的过河船同学想到了一个无聊的玩法:两人同时将两个球放桌面上,同时击出,然后听两颗球撞在一起时的声音。然而他们都对击球的精确度把握得不是很好,所以这两颗球并不一定能相撞。

现在假设桌面无限大,并且绝对光滑,给出两球的初始位置、半径和运动速度,保证两球初始没有接触。无聊的过河船同学想知道两球能否相撞(接触即认为相撞),如果能,他想知道两球相撞的时间(从两人击球时开始计时),如果不能,他想知道全过程中两球距离的最小值,这里两球距离的定义为两球上任取两个点的距离的最小值,数据保证这种情况下答案不小于。请注意,冰球是个圆柱体,从空中往下看就是一个圆,且在这个问题中,冰球的高度可以忽略不计。

Input

第一行是一个正整数,表示测试数据的组数,

每组测试数据包含两行,

第行包含五个绝对值不大于的整数,表示第个球的初始位置、半径和运动速度。

Output

对于每组测试数据,若两球能相撞,输出两球相撞的时间,否则输出全过程中两球距离的最小值,相对误差不超过即可,

也就是说,令输出结果为 ,标准答案为 ,若满足 ,则输出结果会被认为是正确答案。

Sample Input

2
0 0 2 1 0
11 0 1 -1 0
0 0 2 1 0
11 5 1 -1 0

Sample Output

4.0000000000
2.0000000000

Hint

对于第一组样例,两球在击球后4.0秒时发生碰撞,

对于第二组样例,两球不发生碰撞,且在击球后5.5秒时两球距离最近,此时距离为2.0。

Source

第十四届北京师范大学程序设计竞赛决赛

Author

quailty
解:

设时间为t时两个球相撞或者两个球距离最近,用t可以表示出两个球的坐标 Q1( x1+t*vx1  ,  y1+t*vy1)  Q2(  x2+t*vx2   ,    y2+t*vy2)  ,

Q1Q2的距离=  aqrt{(x1-x2)^2  +(y1-y2)^2   } =r1+r2;     整理方程得到一个关于t 的一元二次方程  sqrt( a t^2  +  b t + c )=  r1+r2;

求解该方程,分a=0和a!=0,a!=0,求解 △<0,△=0,△>0,当△<0时无解,求解方程左边的最小值 ,即 t = -b/(2*a),t>0, 带入方程得 d= sqrt ((4ac-b^2)/(4a) ),ans=d-(r1+r2);   t<0 ,ans=sqrt(c)-(r1+r2) 。 当△>=0时,ans=min(t1,t2)。当a=0,时,ans=sqrt(c)-(r1+r2)。

又复习了一遍初中知识

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
using namespace std;
double solve(double a,double b,double c)
{
    double dat=b*b-4.0*a*c;
    if(dat<0)
        return -1;
    double x1= ( -b+sqrt(dat) )/2.0/a;
    double x2= ( -b-sqrt(dat) )/2.0/a;
     if(x2>=0.0)
    return x2;
    if(x2<0&&x1>0)
        return x1;
    if(x1<0&&x2<0)
        return -1;
}
int main()
{
    int t;
    double x1,y1,r1,vx1,vy1;
    double x2,y2,r2,vx2,vy2;
    double x,vx,y,vy;
    double a,b,c;
    double R;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf%lf%lf%lf",&x1,&y1,&r1,&vx1,&vy1);
        scanf("%lf%lf%lf%lf%lf",&x2,&y2,&r2,&vx2,&vy2 );
        x=x1-x2;///c
        y=y1-y2;///c
        vx=vx1-vx2;///a
        vy=vy1-vy2;///a

        a=vx*vx+vy*vy;
        c=x*x+y*y;
        b=2.0*(x*vx+y*vy);
        R=1.0*(r1+r2)*(r1+r2);
        double t=-1.0*b/2.0/a;
        if(a!=0)
        {
            double ans=solve(a,b,c-R);
            if(ans<0&&t<0)
            printf("%.10lf\n",sqrt(c)-r1-r2);

            if(ans<0&&t>=0)
            printf("%.10lf\n",sqrt( (4.0*a*c-b*b) /(4.0*a) )-r1-r2);

            if(ans>=0)
            printf("%.10lf\n",ans);
        }
        else
        printf("%.10lf\n",sqrt(c)-r1-r2);
    }
    return 0;
}


你可能感兴趣的:([置顶] 计算几何--bnu51638)