牛客oj 习题2.11坠落的蚂蚁(模拟) && poj1852Ants(贪心)(蚂蚁问题)

两题都是蚂蚁爬杆问题。。所以放在一起了。

第一个是复试题,因为不同蚂蚁撞在一起交换速度,所以分情况,一动一不动相当于接力,两个相向相当于换位。所以对于速度为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;
}
发布了411 篇原创文章 · 获赞 72 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/Flynn_curry/article/details/104379874