基本思想:
这题考察的是详细的数学思维,使用模拟一步一步枚举的话并不能解决蚂蚁的碰头问题,因为蚂蚁碰头可以不在整数位置,所以很难去解决;
最简单的思路:
对于一只感染的蚂蚁,当他向一个方向前进时,必然碰到和他相向而行的蚂蚁,这些蚂蚁必被感染,这点毫无疑问;
但是由于碰到后会两个蚂蚁都会改变方向,所以可以看作第一只蚂蚁仍然不改变方向前进,继续感染相向而行的蚂蚁;
而第二只蚂蚁穿过第一只蚂蚁,感染和第一只蚂蚁同向的后续蚂蚁;
由于所有蚂蚁速度相同,所以不涉及追及问题,也就是上述的两种情况:
1.若存在和第一只感染蚂蚁相向而行的蚂蚁,则全部感染;
2.若第一种情况成立,则还要计算得到和第一只蚂蚁同向,且在它后面的所有蚂蚁;
第二种情况比较难以计算,需要注意一下;
关键点:
就是数学方法;
#include<iostream> #include<stdlib.h> #include<stdio.h> #include<vector> #include<string> #include<math.h> #include<algorithm> #include<cstring> using namespace std; using std::vector; int main(){ int n; int f; int a; cin >> n; if (n == 0) { cout << 0; return 0; } cin >>f; int cnt = 1; int cnt_1 = 0; bool flag = false; for (int i = 1; i < n; i++) { cin >> a; if (f > 0) { //如果第一支蚂蚁向右走; if (a<0 && abs(a)>f) { cnt++; //右边有蚂蚁相向而行; //则说明地一只蚂蚁左边的必被感染; flag = true; } if (a > 0 && a < f) { //左边有蚂蚁跟地一只蚂蚁同向,需要统计; cnt_1++; } } else { //如果第一只蚂蚁向左走; if (a > 0 && abs(f) > a) { cnt++; //左边有蚂蚁和地一只蚂蚁相向而行; //说明右边的蚂蚁比被感染; flag = true; } if (a < 0 && abs(f) < abs(a)) { //右边同向的蚂蚁需要统计; cnt_1++; } } } if (flag) cout << cnt_1 + cnt; else cout << cnt; }
关键点: