-
题目描述:
-
一根长度为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\n",ans); 59 } 60 else { 61 int tmp = right - left; 62 int ans = pos[Apos + left+1]; 63 printf("%d\n",ans); 64 } 65 } 66 return 0; 67 }