zoukankan      html  css  js  c++  java
  • Codeforces Beta Round #34 (Div. 2) E. Collisions

    E. Collisions
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    On a number line there are n balls. At time moment 0 for each ball the following data is known: its coordinate xi, speed vi (possibly, negative) and weight mi. The radius of the balls can be ignored.

    The balls collide elastically, i.e. if two balls weighing m1 and m2 and with speeds v1 and v2 collide, their new speeds will be:

    .

    Your task is to find out, where each ball will be t seconds after.

    Input

    The first line contains two integers n and t (1 ≤ n ≤ 10, 0 ≤ t ≤ 100) — amount of balls and duration of the process. Then follow n lines, each containing three integers: xivimi (1 ≤ |vi|, mi ≤ 100, |xi| ≤ 100) — coordinate, speed and weight of the ball with index i at time moment 0.

    It is guaranteed that no two balls have the same coordinate initially. Also each collision will be a collision of not more than two balls (that is, three or more balls never collide at the same point in all times from segment [0;t]).

    Output

    Output n numbers — coordinates of the balls t seconds after. Output the numbers accurate to at least 4 digits after the decimal point.

    Sample test(s)
    input
    2 9
    3 4 5
    0 7 8
    output
    68.538461538
    44.538461538
    input
    3 10
    1 2 3
    4 -5 6
    7 -8 9
    output
    -93.666666667
    -74.666666667
    -15.666666667

     因为数据量很少,直接暴力求解即可,细节问题不少,WA了多次。更悲催的是,codeforces上用gun C++编译在test 24出错,但是本机测试答案却无误,用ms 2010编译就AC了。估计是浮点数的精度问题,两种编译器的处理方式有异……

    AC Code:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <map>
    #include <algorithm>
    #include <string>
    
    using namespace std;
    
    const double MAXN = 10000000.000000;
    const double eps = 10e-6;
    const double zero = 0.000000;
    vector<int> idx;
    
    int main()
    {
        int n;
        double t;
        double x[102], v[102], m[102];
        while(scanf("%d %lf", &n, &t) != EOF)
        {
            for(int i = 0; i < n; i++)
                scanf("%lf %lf %lf", &x[i], &v[i], &m[i]);
            while(fabs(t - zero) > eps)
            {
                double min = t;
                double tmp;
                idx.clear();
                for(int i = 0; i < n; i++)
                {
                    for(int j = i + 1; j < n; j++)
                    {
                        tmp = MAXN;
                        if(fabs(x[i] - x[j]) < eps) continue;  //两个球碰撞之后的瞬间在同一位置
                        if(v[i] * v[j] > zero)
                        {
                            if(v[j] == v[i]){}
                            else if(x[i] > x[j])
                                tmp = (x[i] - x[j]) / (v[j] - v[i]);
                            else
                                tmp = (x[j] - x[i]) / (v[i] - v[j]);
                        }
                        else
                        {
                            if(v[j] == zero && v[i] == zero){}
                            else if(x[i] > x[j] && v[i] <= zero && v[j] >= zero)
                                tmp = (x[i] - x[j]) / (-v[i] + v[j]);
                            else if(x[i] < x[j] && v[i] >= zero && v[j] <= zero)
                                tmp = (x[j] - x[i]) / (-v[j] + v[i]);
                        }
                        if(tmp > zero && min >= tmp)  //可能有多对球在不同地点同时碰撞,故而min>=tmp而非min>tmp
                        {
                            if(min > tmp)
                            {
                                idx.clear();
                                //当多对球同时碰撞时才需要存储多对下标,不然一定要清空原来
                                //存储的一对下标
                            }
                            min = tmp;
                            idx.push_back(i);
                            idx.push_back(j);
                        }
                    }
                }
                t -= min;
                for(int i = 0; i < n; i++)
                {
                    x[i] = x[i]  + v[i] * min;
                }
                int i, j;
                for(vector<int>::iterator it = idx.begin(); it != idx.end(); it += 2)
                {
                    i = *it, j = *(it + 1);
                    double vi = v[i];
                    //更新v[j]时需要用到v[i],而v[i]在更新v[j]前已经更新,故而要备份v[i]
                    v[i] = ((m[i] - m[j])*v[i] + 2.000000 * m[j]*v[j]) / (m[i] + m[j]);
                    v[j] = ((m[j] - m[i])*v[j] + 2.000000 * m[i]*vi) / (m[j] + m[i]);
                }
            }
            for(int i = 0; i < n; i++)
                printf("%.5lf
    ", x[i]);
        }
    }
  • 相关阅读:
    前端之多行省略号显示...
    关于跨域的那点事情
    前端之碰到数组等基础类型改变而试图无更新
    前端小记之vue下载二进制文件
    防抖和节流
    前端小记之style三元运算符
    Django之坑TemplateDoesNotExist
    MYSQL之net start mysql 1067报错
    vscode之创建django项目
    phpstorm使用mysql出现timezone问题
  • 原文地址:https://www.cnblogs.com/cszlg/p/3208314.html
Copyright © 2011-2022 走看看