POJ 1853 ants

博客探讨了POJants1853问题的解决方案,涉及蚂蚁在杆上行走的问题。作者指出,关键在于理解蚂蚁碰撞等价于路径交换,并分析了蚂蚁单向行走和碰撞时的最长时间与最短时间。通过计算每个蚂蚁到杆两端的最远和最近距离来确定最长时间,而最短时间则考虑所有蚂蚁不碰撞的情况。代码示例展示了如何实现这一算法。
摘要由CSDN通过智能技术生成

POJ ants 1853

题型

对于这类题目,没有具体的归类,书上称为简单思维题,解题方法就是抽象出具体场景,找出规律
  这句话是AC之后写的,做这种题目重要的是考虑周全,比如说我考虑到了蚂蚁碰头和都不碰头(单向)的情况,但是忽略了双向也可以不碰头的情况,比如A向左,B向右,这样也不会碰头,然后就是思路清晰,比如在证明等价交换相等的时候,杆上两只蚂蚁碰一次和三只蚂蚁碰两次的道理是一样的,不管杆上有几只蚂蚁,碰头的时候都看成是两只蚂蚁。

题解

这道题笔者一开始想的是把蚂蚁所有可能的方向都测试一边,就是排列组合出所有的情况,但是发现时间复杂度太大了,2n ,是指数型增加的,当n稍微大一点的时候,肯定遭不住,只好作罢。
换一个思路想一下,蚂蚁只有两个方向能走,要么存在碰头,要么全部走单向。

  1. 第一种情况:存在碰头(证明等价交换)
    假设棒子10cm长,蚂蚁A向左走,离右端7cm,蚂蚁B向右走,距离右端3cm,相遇之后,A向左走到头,B右走到头,实际距离并没有改变,相当于A走完了B要走的路,B走完了A要走的路,就这么简单,不管n等于多少,3只蚂蚁也好,4只也好,只要存在碰头,就可以认为两只蚂蚁等价交换了剩余路程,也可以看作是两只蚂蚁互换了身份,要走的路没有变多也没有变少。
    那么最长时间难道就是所有蚂蚁都要交换一次?错了,最长的时间就是找出所有蚂蚁中的某一只蚂蚁从当前点到杆A端的距离(X)和到B端的距离(L-X)两者的最大值C,C表示的是一只蚂蚁在杆上所花的最长时间,我们有n只蚂蚁,所以要计算n次,找出n个最长时间中的最长时间

for(int ix=0;ix<n;++ix){ maxT=(maxT,max(x[ix],L-x[ix])); }

在这里插入图片描述

  1. 都是单向
    一旦出现交换方向,就意味着有两只蚂蚁要走的路程一定会等于杆的长度,那么倘若没有交换,则所走路程一定小于存在交换时的长度
    因此最短时间我们只需要考虑不存在交换的情况。
    和上面i一样,我们比较蚂蚁到A端和到B端的最短时间C,C表示的是一只蚂蚁在杆上能停留的最短时间,我们有n只蚂蚁,所以我们只要找出所以最短时间中最长的时间即可。

代码如下

#include<cstdio>
#include<algorithm>
#include<vector>

using namespace std;
int main(){
    int t,n,l;
    vector<int>X;
    scanf("%d",&t);
    while(t--){
        X.clear();
        //读入数据
        scanf("%d %d",&l,&n);
        for(int ix=0;ix<n;++ix){
            int x;
            scanf("%d",&x);
            X.push_back(x);
        }
        vector<int>::const_iterator it=X.begin();
        int max_t=0,min_t=0;
        for(;it!=X.end();++it){
            max_t=max(max_t,max(*it,l-*it));
            min_t=max(min_t,min(*it,l-*it));
        }
        printf("%d %d\n",min_t,max_t);
        
    }
    system("pause");
    return 0;
}

在这里插入图片描述
AC贴图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值