• zoj 3409 KKV


    KKV

    Time Limit: 10 Seconds      Memory Limit: 65536 KB      Special Judge

    KKV (short for Kinetic Kill Vehicle), a new kind of projectile, is a powerful weapon and has a great ability to move in the space. PLA developed a new missile based on the technology of KKV, and this kind of missile can launch and fly in the space, find the target and destroy it.

    Now the launch site of the KKV missile is at position (0, 0, 0), the missile will fly through N polygonal lines in order and its initial speed is zero. The initial mass of the missile is M, the mass without fuel is m, and every time the missile can eject some fuel which always has a mass of m0, and the eject speed (scalar) is always v0 (absolute, not relative).

    Now give you the N points in order which are the endpoints of the N polygonal lines(The first line is from (0, 0, 0) to the first point, the second line is from the first point to the second point, the third line is from the second point to the third point, etc.), your task is to calculate the time between the KKV missile's launching and its arriving at the Nth point.

    The KKV missile is so small that its size can be ignored. It can only and have to eject fuel at all the endpoints except the Nth point, and every time if it ejects fuel, the KKV missile always selects the direction that can make it fly along the next line, and have the largest speed. The motion of the KKV missile obey the principle of momentum conservation, thus m1 × v1 + m2 × v2 = m1 × v'1 + m2 × v'2, here m1 and m2 are the mass of two objects, v1 and v'1 are the original speed and the speed after collision of m1v2 and v'2 are the original speed and the speed after collision of m2.

    But you know that sometimes the PLA will hide some real abilities about their weapons, so sometimes the data might not be valid to this kind of KKV. So, if you find this thing happens, just output "Another kind of KKV.".

    Input

    There are multiply test cases. Each case begins with a line contains 5 integers N M m m0 and v0, here 1 ≤ N ≤ 40, 1 ≤ m < M - N × m0M ≤ 200000, 1 ≤ m0, 1 ≤ v0 ≤ 100. Then the following N lines each contains three integers xi yi and zi(1 ≤ i ≤ N), indicate the ith point's coordinates. Here -100000 ≤ xiyizi ≤ 100000, and we guarantee that every pair of consecutive lines won't be perpendicular to each other, and the next line won't be in the negative direction of its previous one. (This means three consecutive points cannot be { (0, 0, 0), (0, 0, 3), (1, 1, 2) } or { (0, 0, 0), (0, 0, 3), (1, 1, 3) }, or something like these)

    Output

    For each test case, output the total flying time of the KKV missile in one line, with two digits after the decimal point, if the data cannot satisfy the KKV missile's flying path, output "Another kind of KKV." instead. If the relative error is no more than 1e-6, the answer will be accepted.

    Sample Input

    2 10 1 2 5
    2 2 2
    4 4 4
    2 10 2 2 2
    0 0 3
    2 2 5
    4 10 1 2 20
    0 0 40
    0 0 80
    10 10 110
    10 20 115
    

    Sample Output

    3.81
    10.50
    Another kind of KKV.

    最后还是没有做出来……
    看的别人的代码,(地址:http://www.cppblog.com/aswmtjdsj/archive/2011/07/05/150199.html)惭愧……主要解题思路就是知道每条线段的向量,然后设一个参数k,通过向量表示速度,然后解方程就可以了
    因为题目中说了,不能反向,所以,k不能为负值,所以一元二次方程的解只需要取比较大的就可以了。
    自己写了很久没有写出来,关键是数据的结构没有选择好,显然用结构体比较方便表示向量和有方向的速度。
    学习一下别人写代码的方法。
    看着别人的代码敲的时候还是各种错,以后自己再敲一遍,还有,出现公式推导的时候,在纸上一定要写清楚,千万别抄错了……
     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstdio>
     4 #include <cstdlib>
     5 #include <cstring>
     6 using namespace std;
     7 const double eps = 1e-10;
     8 inline double sqr(double x){return x*x;}
     9 struct point{
    10   double x, y, z;
    11   void input(){
    12     scanf("%lf%lf%lf", &x, &y, &z);
    13   }
    14 }p[50];
    15 struct vect{
    16   double x, y, z, mod;
    17   void init(point p, point q){
    18     x = q.x - p.x; y = q.y - p.y; z = q.z - p.z;
    19     mod = sqrt(sqr(x) + sqr(y) + sqr(z));
    20   }
    21   double cal(){
    22     return mod = sqrt(sqr(x) + sqr(y) + sqr(z));
    23   }
    24 }vec[50], v[50];
    25 double scalar(vect a, vect b){
    26   return a.x * b.x + a.y * b.y + a.z * b.z;
    27 }
    28 void function(double a, double b, double c, bool &mark, double &k){
    29   double det = sqr(b) - 4 * a * c;
    30   if (det < eps && fabs(det) > eps){
    31     mark = false; return;
    32   }
    33   else {
    34     mark = true; k = (-b + sqrt(det)) / (2.0 * a);
    35     return;
    36   }
    37 }
    38 void solve(int n){
    39   double m, m1, mt, m0, v0, k, t = 0.0; int i;
    40   scanf("%lf%lf%lf%lf", &m, &m1, &m0, &v0);
    41   p[0].x = p[0].y = p[0].z = 0.0;
    42   for (i = 1; i <= n; ++i){
    43     p[i].input(); vec[i-1].init(p[i-1], p[i]);
    44   }
    45   mt = m - m0;
    46   k = sqrt(sqr(m0) * sqr(v0) / (sqr(mt) * sqr(vec[0].mod)));
    47   v[0].x = k * vec[0].x; v[0].y = k * vec[0].y; v[0].z = k * vec[0].z;
    48   t += (vec[0].mod / v[0].cal());
    49   for (i = 1; i < n; ++i){
    50     double a, b, c, k1;
    51     a = sqr(mt - m0) * sqr(vec[i].mod);
    52     b = -2 * mt * (mt - m0) * scalar(vec[i], v[i-1]);
    53     c = -sqr(m0) * v0 * v0 + sqr(mt) * sqr(v[i-1].cal());
    54     bool mark = false;
    55     function(a, b, c, mark, k1);
    56     if (mark){
    57       if (k1 > 0) k = k1;
    58       v[i].x = k * vec[i].x; v[i].y = k * vec[i].y; v[i].z = k * vec[i].z;
    59       t += (vec[i].mod / v[i].cal());
    60     }
    61     else {
    62       printf("Another kind of KKV.\n"); return;
    63     }
    64     mt -= m0;
    65   }
    66   printf("%.2lf\n", t);
    67 }
    68 int main(void){
    69 #ifndef ONLINE_JUDGE
    70   freopen("in", "r", stdin);
    71 #endif
    72   int n; 
    73   while (~scanf("%d", &n)){
    74     solve(n);
    75   }
    76   return 0;
    77 }

    以后自己再敲一遍……

    最讨厌那种只有代码的解题报告了……所以我还是写一点儿解释吧~

    分步解答:

    输入的 m 就是火箭和燃料的总质量,相当于原题中的M,m1就是火箭的质量,不包括燃料,m0就是每次喷出燃料的质量,v0是喷出的燃料的绝对速度。

    根据动量守恒定律

    (1)从原点开始到第一个点:

    0 = (m - m0) * v1(x, y, z) + m0 * v0(x, y, z);

    v1(x, y, z) = k * vec(x, y, z);

    V0x * V0x + v0y * V0y + V0z * V0z = V0 * V0;

    其中vec(x, y, z)是向量,由原点指向第一个点。

  • 相关阅读:
    SQL(4)— Date、order by
    步入三十(二)
    【js】特殊字符转义
    【ionic】项目中$ionicModal简单用法
    【ionic】常见问题处理
    【js】视频截图
    实现笔记本拔除电源后修改屏幕缩放比例
    激活 公众号java
    【Golang】基于beego/orm实现相同表结构不同表名的分表方法实现
    .Net Cors 跨域配置域名通配符
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/2972006.html
Copyright © 2020-2023  润新知