题目1159:坠落的蚂蚁

来源:互联网 发布:淘宝的返现怎么使用 编辑:程序博客网 时间:2024/04/27 14:25

题目链接地址:http://ac.jobdu.com/problem.php?pid=1159

题目看起来很复杂而且要模拟的话也比较麻烦,但是如果仔细观察的话就会发现这样一个事实:两只非A(A蚂蚁是刚开始静止的那只蚂蚁)蚂蚁相碰的时候交换各自的速度其实相当于两只蚂蚁还是各走各的路,没有碰头,速度不变。

然后假设蚂蚁A的位置是pos
基于上面的结论
那么在pos左边并且初速度向左-1的蚂蚁   还有  在pos右边并且初速度向右+1的蚂蚁不会对A造成任何影响
这两种类型的蚂蚁可以忽略掉

然后就剩下在pos左边速度向右的蚂蚁(设为left类蚂蚁)和在pos右边速度向左的蚂蚁(设为right类蚂蚁)了
还要观察出一个结论是 题目实质上每个蚂蚁的相对位置不会变化
也就是说假设a在b左边 那么不可能在一个时间a跑b的右边去了
可以模拟一下 然后把模型转化
这样可以推出蚂蚁A不会掉落的情况只有是在它左边left类蚂蚁个数==它右边right类蚂蚁个数
其它情况蚂蚁A都会掉下去 
你可以想象成蚂蚁A左边离它最近的蚂蚁和右边离它最近的蚂蚁抵消掉 左边第二近的与右边第二近的抵消掉......
至于掉到哪边 就看left和right类蚂蚁哪个少些 哪个少它就掉哪边
掉的时间点: left蚂蚁和right蚂蚁其中一类抵消完后剩下的第一个蚂蚁掉落时间就是A的掉落时间了。

C++代码如下:

#include<iostream>#include<algorithm>using namespace std;const int N = 102;int aa[N],bb[N];        //left蚂蚁位置 right蚂蚁位置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];}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;else if(nl>nr){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;}


0 0