27 坠落的蚂蚁 北大复试 C++

一根长度为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!”

示例1

输入
4
10 1
90 0
95 -1
98 -1
输出
98

题解

蚂蚁的相对位置永远不变
怎么判断蚂蚁不会坠落,有两种情况————
第一种:静止的蚂蚁两边的蚂蚁都不会碰到这只蚂蚁,也就是说,左边的往左走,右边的往右走
第二种:蚂蚁的右边有向左走的,左边有向右走的,按照一般的理解一开始静止的蚂蚁一定
是会掉下去的,但是注意一开始提到的那个逻辑,蚂蚁的相对位置不变,并且移动方向也不变!
什么意思呢,比如整个树枝上向左走有n个,向右走有m个。那么在任何时间向左走和向右走的
数量都是n和m,这时候结合蚂蚁的相对位置,在无限的时刻,向左走的n只蚂蚁都掉下了树枝,
这n只不一定都是原来初始状态向左走的,但一定是一开始左边的n只蚂蚁,因为相对位置不变。
同理,右边m只也都掉出去了,那么如果n==m,并且静止的蚂蚁左右都有n(m)只。那么,在某个时刻,
左边n只无论之前是向哪里走的,一定都下去了。
所以,我们把结论推广,只要静止的蚂蚁左边的蚂蚁数量,等于所有蚂蚁中往左走的数量,
亦或者右边的等于向右走的那么它就不会掉下去。

那么,怎么判断蚂蚁什么时候下去呢
这时候肯定能确定这只蚂蚁左右数量不等了。接下来就是很巧妙的思想了,如果该蚂蚁
左边的蚂蚁数量小于向左走的蚂蚁数量,那么它总会加入向左走的大军最后掉落。这时候
我们宏观的去看,我们定位所有在向左走的蚂蚁,并且定位静止的那只蚂蚁的位置,并且
标记为k(第k个蚂蚁),这时开始移动,我们看不到蚂蚁之间交换速度,我们只知道他们
像是穿过对方继续往下走。让蚂蚁继续走,直到某一刻我们观察到第k只向左走的蚂蚁
掉下去了,暂停。现在考虑所有蚂蚁的相对位置不变!如果是第k个向左走的蚂蚁下去了
那么他之前的向左走的蚂蚁都下去了,反映到相对位置上来说,就是树枝上左边k-1只都下去了,
那么这一瞬间掉下去的想必就是相对位置在第k的蚂蚁了————也就是原来静止的那只。
也就是说一开始所有向左走的蚂蚁中,第k个蚂蚁要走多远,就是最终答案

c++11

#include<iostream>
#include<algorithm>
 
using namespace std;
const int N = 102;
 
int aa[N],bb[N];        //aa是右边蚂蚁最后位置 bb是左边蚂蚁最后的位置
int a[N],b[N];//初始蚂蚁位置、速度
int main()
{
    int n;
    while(cin>>n)
    {
        int pos=0;              //蚂蚁A位置
        for(int i=1;i<=n;++i)
        {
            cin>>a[i]>>b[i];
            if(b[i]==0) pos=a[i];//蚂蚁A是速度为0 的
        }
        int nl=0,nr=0;//左右蚂蚁数量
        for(int i=1;i<=n;++i)
        {
            if(a[i]<pos && b[i]>0) aa[++nl]=100-a[i];
            //将左边向右走的蚂蚁放到右边
            else if(a[i]>pos && b[i]<0) bb[++nr]=a[i];
            //将右边向左走的蚂蚁放到左边
        }
        if(nl==nr) cout<<"Cannot fall!"<<endl;
        //如果此时左右蚂蚁数量相等,那么A不会掉落
        else if(nl>nr)
        {
            //左边蚂蚁数量多的时候,排序,输出相对位置不变的A蚂蚁最后的位置,即A掉下用的时间
            sort(aa+1,aa+nl+1);
            cout<<aa[nr+1]<<endl;
        }
        else
        {
            sort(bb+1,bb+nr+1);
            cout<<bb[nl+1]<<endl;
        }
    }
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值