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]);
        }
    }
  • 相关阅读:
    威联通NAS 网站无法登录,可以ssh情况下重启设备方法
    NSNotification的几点说明
    使用UIDatePicker
    scrollView的几个属性contentSize contentOffset contentInset
    创建标题栏,UINavigationBar的使用
    点击tablecell中的一个按钮,确定cell所在的行
    UITextView被键盘遮挡的处理
    UITableViewCell中的UILabel添加手势没有响应的解决方法
    将NSArray反向排序
    图片的左右摆动
  • 原文地址:https://www.cnblogs.com/cszlg/p/3208314.html
Copyright © 2011-2022 走看看