zoukankan      html  css  js  c++  java
  • 弹性碰撞问题:Ants+Linear world

    题目一:Ants

    传送门

    题目描述

     输入

     输出

     样例

    样例输入

    2
    10 3
    2 6 7
    214 7
    11 12 7 13 176 23 191
    View Code

    样例输出

    4 8
    38 207
    View Code

    分析

    一句话题意:有n只蚂蚁在木棍上爬行,每只蚂蚁的速度都是每秒1单位长度,现在给你所有蚂蚁初始的位置(蚂蚁运动方向未定),蚂蚁相遇会掉头反向运动,让你求出所有蚂蚁都·掉下木棍的最短时间和最长时间。

    如果没有思路的话,我们可以先模拟一下

     这是一个长度为10的木棍,我们假设6、8两个位置上分别有一只蚂蚁

    如果它们都朝着左边走,那么6号节点上的蚂蚁需要花费6s才能从木棍上掉下来,8号节点上的蚂蚁需要花费8秒才能掉下来

    如果都朝着右边走,那么6号节点上的蚂蚁需要花费4s才能从木棍上掉下来,8号节点上的蚂蚁需要花费2秒

    如果6号节点朝左边走,8号节点朝右边走,那么6号节点上的蚂蚁需要花费6s才能从木棍上掉下来,8号节点上的蚂蚁需要花费2秒

    以上两种情况这两只蚂蚁都不会相遇,因此我们不用考虑蚂蚁相遇的情况

    那么我们来模拟一下两只蚂蚁相遇的情况

    假设6号节点上的蚂蚁向右走,8号节点上的蚂蚁向左走,那么一秒后,它们将会在7号节点相遇

    这是,原本在6号节点的蚂蚁会掉头向1号节点的方向走,而原本在8号节点上的蚂蚁则会掉头向10号节点的方向走

    我们用蓝笔表示6号节点上的蚂蚁的运动情况,用绿笔表示8号节点上蚂蚁的运动情况

    这时我们可以画出如上图的运动图像,如果还是没有看出什么的话,我们可以将上面的蓝色线与绿色线换一下颜色

     

    这时我们发现,虽然两个蚂蚁相遇之后调转了方向,但是他们的速度并没有变

    换句话说,我们可以把这个相遇折返的运动看成相遇不折返的运动

    因此,我们可以无视所有的相遇,直接求每个蚂蚁到两个端点所需要的时间,最后再分别取最大值和最小值

    代码

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 using namespace std;
     6 int a[1000010];
     7 int main(){
     8     int t;
     9     scanf("%d",&t);
    10     while(t--){
    11         memset(a,0,sizeof(a));
    12         int m,n;
    13         scanf("%d%d",&m,&n);
    14         for(int i=1;i<=n;i++){
    15             scanf("%d",&a[i]);
    16         }
    17         sort(a+1,a+1+n);
    18         int mmin=-0x3f3f3f3f,mmax=-0x3f3f3f3f;
    19         for(int i=1;i<=n;i++){
    20             mmin=max(mmin,min(a[i],m-a[i]));
    21             mmax=max(mmax,max(a[i],m-a[i]));
    22         }
    23         printf("%d %d
    ",mmin,mmax);
    24     }
    25     return 0;
    26 }
    View Code

     题目二:Linear world

     题目描述

    圆盘是平的,没有真正的地平线。任何敢于冒险的水手,如果因为长时间盯着鸡蛋和桔子,然后出发到相反的地方,很快就会明白,为什么远航的船只有时看起来像是消失在世界的边缘,是因为它们正在消失在世界的边缘。(特里·普拉切特-魔法的颜色)

    不久前,人们曾经相信他们生活在二维世界里,如果他们在一个方向上旅行足够长的时间,他们会从边缘掉下来。即使证明地球是圆的,他们中的一些人仍然害怕去南半球旅行。

    试着想象一个一维(线性)世界。在这样的世界上,只有两个可能的方向(左和右)。这个世界上所有的居民都是在同一时间被创造出来的,突然他们都开始向一个或另一个方向移动(都以同样的恒定速度)。如果两个居民相遇,他们礼貌地互致问候,然后转身朝相反的方向移动。当一个居民到达世界的尽头时,他就消失了。

    你的任务是确定,对于给定的创造场景,哪一个居住者和何时(从创造的时刻算起)将是最后一个倒下的人。您可以假设交换问候语和转身所需的时间为0。

    输入

    输入由创建时刻的多个描述(数据集)组成。文件结构如下:

    N
    LV
    DIR POS NAME
    ...

    第一行定义了居民人数(N<32000)。以值N=0开头的数据集表示输入文件的结尾。第二条线包含世界长度L(浮标)和居民速度V(浮标)。这两个值都是正的。在接下来的N行中,关于居民的数据按POS(正方向)增加的顺序给出:

    DIR–初始方向(“p”或“p”表示正方向,“n”或“n”表示负方向)

    POS—创建时的位置(0<=POS<=L)

    NAME–居民姓名(最多250个字符)

    一行中的输入值至少用一个空格分隔,并且输入中不会有空行。您可以假设输入总是正确的,并且每个数据集只有一个唯一的解决方案。

    输出

    输出由每个输入数据集一行组成。第一个值应该是当最后一个居住者从创造之时起,从线性世界倒下的时间。值应在13个字符宽的字段中被截断为两个小数位。第二个值应该是居民的名字。值应使用单个空格字符分隔。

    样例

    样例输入

    1   
    13.5 2   
    p 3.5 Smarty  
    4  
    10  1  
    p  1  Helga  
    n 3 Joanna  
    p  5  Venus  
    n  7  Clever  
    0
    View Code

    样例输出

             5.00 Smarty
             9.00 Venus
    View Code

    分析

    思路和上一道题一样,不过是换了一种方式

    对于这个题目,最后一个人掉落的时间显然很好确定

    我们假设在碰撞过程中不交换标号,那么我们可以很容易把时间最长的人找出来

    然后看在他行走的方向和他方向相反的人有几个,有多少人就会有多少次碰撞(因为速度一样),假设有k个。因为每次碰撞这个人的名字都只能传给他方向上的前面一个人,所以这个人的名字就向前面传递了k次

    这道题细节比较多,大家有兴趣的话可以做一做,特别要注意的是最后的输出格式

    总结

    1、这种模型都可以看做两个球在碰撞之后并不返回,而是继续向前,只不过交换了一下标号

    2、两个小球在碰撞后速度应该是不变的,要是改变这种方法就不适用了

  • 相关阅读:
    《孙子兵法》【行军第九】
    《孙子兵法》【虚实第六】
    《孙子兵法》【地形第十】
    企业无线局域网的搭建
    企业无线局域网的搭建
    UDDI
    (转载)Linux:Ldd命令介绍及使用方法
    (转载)传递给const引用形参的实参要求
    (转载)千万不要把bool设计成函数参数
    (转载)Linux下如何修改终端提示符?
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/12700770.html
Copyright © 2011-2022 走看看