两题都是蚂蚁爬杆问题。。所以放在一起了。
第一个是复试题,因为不同蚂蚁撞在一起交换速度,所以分情况,一动一不动相当于接力,两个相向相当于换位。所以对于速度为0的蚂蚁来说,如果左右两边都有一只朝自己走的蚂蚁,那方向不变但初始位置变成最后交换位置的蚂蚁初始位置。
仔细想想(想的过程就不说了)就可以变成首先计算出左右两方各有多少蚂蚁,把能够遇见的蚂蚁当成同归于尽,不动蚂蚁落下的时间就是未同归于尽第一个活着的蚂蚁落下的时间,不动蚂蚁落下的方向就是左右双方数量多的一方的方向。最后模拟即可。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#include <cmath>
#include <climits>
using namespace std;
const int INF = INT_MAX;
int FindCommon(int x, int y){
int minabs = min(abs(x), abs(y));//找出公共部分(同归于尽部分)的绝对值
if(x+y > 0) return minabs+1;
else if(x+y < 0) return -(minabs+1);
else return 0;
}
int main(){
// freopen("in.txt", "r", stdin);
int N, pos, way, current, change, number, number1, number2;
int stick[105];
while(~scanf("%d", &N)){
memset(stick, 0, sizeof(stick));
number = number1 = number2 = 0;
for(int i = 0; i < N; i++){
scanf("%d %d", &pos, &way);
stick[pos] = way;
if(way == 0) current = pos;
}
change = current;
while(change--){
if(stick[change] == 1) number1++;
if(change == 0) break;
}
change = current;
while(change++){
if(stick[change] == -1) number2--;
if(change == 100) break;
}
number = FindCommon(number1, number2);
int ans, flag = false;
if(number > 0){//正向剩余
change = current;
while(number > 0){
change--;
if(stick[change] == 1) number--;
}
ans = 100 - change;
}
else if(number < 0){//负向剩余
change = current;
while(number < 0){
change++;
if(stick[change] == -1) number++;
}
ans = change;
}
else flag = true;
if(flag) printf("Cannot fall!\n");
else printf("%d\n", ans);
}
return 0;
}
先上题链接:click here
蚂蚁速度相同碰在一起即折回,可以看做双方互不影响。
这题刚开始一看可以模拟,先排个序然后找杆中间左右两个地方的蚂蚁,最小值即离杆最近的蚂蚁朝外走的最大值,最大值即离杆最远的蚂蚁朝里走的最大值。但是这个方法有个缺点,就是边界情况不好讨论。全在杆中间左面或右面,有一只在杆正中间,那还得分情况讨论,,,如果有多只都在杆正中间,还得讨论。。。太麻烦故弃之。。
这题最好的方法就是贪心,其实一开始就该想到贪心的。。遍历所有蚂蚁不断找两方向的最值即可找出。
对了这题数据量1000000,注意定义成全局变量。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#include <cmath>
#include <climits>
using namespace std;
const int MAXN = 1000005;
const int INF = INT_MAX;
int stick[MAXN];
int main(){
// freopen("in.txt", "r", stdin);
int M, L, n;
scanf("%d", &M);
while(M--){
scanf("%d %d", &L, &n);
for(int i = 0; i < n; i++){
scanf("%d", &stick[i]);
}
int maxtime = 0, mintime = 0;
for(int i = 0; i < n; i++){
maxtime = max(maxtime, max(stick[i], L-stick[i]));
mintime = max(mintime, min(stick[i], L-stick[i]));
}
printf("%d %d\n", mintime, maxtime);
}
return 0;
}