• 九度oj 题目1159:坠落的蚂蚁


    题目描述:

        一根长度为1米的木棒上有若干只蚂蚁在爬动。它们的速度为每秒一厘米或静止不动,方向只有两种,向左或者向右。如果两只蚂蚁碰头,则它们立即交换速度并继续爬动。三只蚂蚁碰头,则两边的蚂蚁交换速度,中间的蚂蚁仍然静止。如果它们爬到了木棒的边缘(0或100厘米处)则会从木棒上坠落下去。在某一时刻蚂蚁的位置各不相同且均在整数厘米处(即1,2,3,…99厘米),有且只有一只蚂蚁A速度为0,其他蚂蚁均在向左或向右爬动。给出该时刻木棒上的所有蚂蚁位置和初始速度,找出蚂蚁A从此时刻到坠落所需要的时间。

    输入:

        第一行包含一个整数表示蚂蚁的个数N(2<=N<=99),之后共有N行,每一行描述一只蚂蚁的初始状态。每个初始状态由两个整数组成,中间用空格隔开,第一个数字表示初始位置厘米数P(1<=P<=99),第二个数字表示初始方向,-1表示向左,1表示向右,0表示静止。

    输出:

        蚂蚁A从开始到坠落的时间。若不会坠落,输出“Cannot fall!”

    样例输入:
    4
    10 1
    90 0
    95 -1
    98 -1
    样例输出:
    98

    这道题真的是又绕又难。一开始读题不认真,就没有搞清楚A蚂蚁到底指什么,最后才发现是“有且只有一只蚂蚁A速度为0”,这A也太隐蔽了吧!
    之后研究题目的内容,题目似乎在讲述动量守恒定律。若B蚂蚁撞了A蚂蚁,那么A蚂蚁就会像B蚂蚁一样运行下去。
    那么我们来研究一下A蚂蚁掉落的条件,一定有一只B蚂蚁撞了A蚂蚁,如果A前进的路上还有一只C蚂蚁,那么A会返回来直到碰上B.然后A会停下来,B的速度传给了C,C的速度传给了B.C和B对A的作用相互抵消了。
    向下推之,若A两侧有相同数目相向运动的蚂蚁,则A就不会掉下。
    若A两侧相向运动蚂蚁数目不相同,那么多的那一侧(抵消掉相同的后)离A最近的蚂蚁M会把它的速度传递给A,然后A就会掉下。
    那么这个时间其实就是M运动至边界的时间。

    注意只有在A两侧相向运动的蚂蚁才是有效的蚂蚁,其余都要忽略,另外速度为0的蚂蚁只有一只。
    代码如下
     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <algorithm>
     4 #include <iostream>
     5 using namespace std;
     6 
     7 struct Ant
     8 {
     9     int pos;
    10     int dir;
    11 };
    12 Ant ant[101];
    13 int pos[101];
    14 
    15 int cmp(const void *a, const void *b) {
    16     Ant at = *(Ant *)a;
    17     Ant bt = *(Ant *)b;
    18     return at.pos - bt.pos;
    19 }
    20 
    21 int main(int argc, char const *argv[])
    22 {
    23     int n;
    24     freopen("input.txt","r",stdin);
    25     while(scanf("%d",&n) != EOF) {
    26         for(int i = 0; i < n; i++) {
    27             scanf("%d %d",&ant[i].pos, &ant[i].dir);    
    28         }
    29         qsort(ant, n, sizeof(Ant), cmp);
    30         int left = 0;
    31         int right = 0;
    32         int Apos;
    33         int state = 0;
    34         int j = 0;
    35         for(int i = 0; i < n; i++) {
    36             if(state == 0 && ant[i].dir == 1) {
    37                 pos[j++] = ant[i].pos;
    38                 left++;
    39             }
    40             else if(state == 0 && ant[i].dir == 0) {
    41                 state = 1;
    42                 Apos = j;
    43                 pos[j++] = ant[i].pos;
    44                 
    45             }
    46             else if(state == 1 && ant[i].dir == -1) {
    47                 pos[j++] = ant[i].pos;
    48                 right++;
    49             }
    50         }
    51         if(left == right) {
    52             puts("Cannot fall!");
    53             continue;
    54         }
    55         else if(left > right) {
    56             int tmp = left - right;
    57             int ans = 100 - pos[tmp-1];
    58             printf("%d
    ",ans);
    59         }
    60         else {
    61             int tmp = right - left;
    62             int ans = pos[Apos + left+1];
    63             printf("%d
    ",ans);
    64         }
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    耗时很长的服务器端事件中让客户端得到中间过程信息的合理解决方案(续)
    复杂一点的查询
    耗时很长的服务器端事件中让客户端得到中间过程信息的合理解决方案
    PET SHOP 4.0 初学者分析(项目分解)
    TSQL学习笔记(索引贴)
    存储过程和用户自定义函数
    c#简单的音乐播放器,支持多种格式,可扩展性强
    图片的无级缩放和无级截取(js+.net)
    在线部署web项目(适用于较大型项目)
    约束
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5751019.html
Copyright © 2020-2023  润新知