POJ ants 1853
文章目录
题型
对于这类题目,没有具体的归类,书上称为简单思维题,解题方法就是抽象出具体场景,找出规律
这句话是AC之后写的,做这种题目重要的是考虑周全,比如说我考虑到了蚂蚁碰头和都不碰头(单向)的情况,但是忽略了双向也可以不碰头的情况,比如A向左,B向右,这样也不会碰头,然后就是思路清晰,比如在证明等价交换相等的时候,杆上两只蚂蚁碰一次和三只蚂蚁碰两次的道理是一样的,不管杆上有几只蚂蚁,碰头的时候都看成是两只蚂蚁。
题解
这道题笔者一开始想的是把蚂蚁所有可能的方向都测试一边,就是排列组合出所有的情况,但是发现时间复杂度太大了,2n ,是指数型增加的,当n稍微大一点的时候,肯定遭不住,只好作罢。
换一个思路想一下,蚂蚁只有两个方向能走,要么存在碰头,要么全部走单向。
- 第一种情况:存在碰头(证明等价交换)
假设棒子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])); }
- 都是单向
一旦出现交换方向,就意味着有两只蚂蚁要走的路程一定会等于杆的长度,那么倘若没有交换,则所走路程一定小于存在交换时的长度
因此最短时间我们只需要考虑不存在交换的情况。
和上面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贴图