[UVA] 10881 - Piotr's Ants - 思维(丑陋的)

Piotr's Ants
Time Limit: 2 seconds

"One thing is for certain: there is no stopping them;
the ants will soon be here. And I, for one, welcome our
new insect overlords."

Kent Brockman

Piotr likes playing with ants. He has n of them on a horizontal poleL cm long. Each ant is facing either left or right and walks at a constant speed of 1 cm/s. When two ants bump into each other, they both turn around (instantaneously) and start walking in opposite directions. Piotr knows where each of the ants starts and which direction it is facing and wants to calculate where the ants will end upTseconds from now.

Input
The first line of input gives the number of cases, NN test cases follow. Each one starts with a line containing 3 integers:L ,T and n(0 <= n <= 10000). The nextn lines give the locations of then ants (measured in cm from the left end of the pole) and the direction they are facing (L or R).

Output
For each test case, output one line containing "Case #x:" followed byn lines describing the locations and directions of then ants in the same format and order as in the input. If two or more ants are at the same location, print "Turning" instead of "L" or "R" for their direction. If an ant falls off the polebefore T seconds, print "Fell off" for that ant. Print an empty line after each test case.

Sample Input Sample Output
2
10 1 4
1 R
5 R
3 L
10 R
10 2 3
4 R
5 L
8 R
Case #1:
2 Turning
6 R
2 Turning
Fell off

Case #2:
3 L
6 R
10 R


Problemsetter: Igor Naverniouk

Alternate solutions: Frank Pok Man Chu and Yury Kholondyrev




小紫上面的一道题,好像很多地方都把这个当作入门题,不知道为什么,不过其中的思维确实很巧妙。


给我们一个长为L的木条儿,上面有N只蚂蚁,每只蚂蚁有他自己的位置和朝向,速度都是每秒前进1,两只蚂蚁互相碰撞后会掉头往相反的方向运动,根据输入的每只蚂蚁的顺序,求时间T后每只蚂蚁的位置以及状态(朝向,掉下木条,正在相碰)


这道题有两个关键,第一个就是如果我们将蚂蚁进行排序,在蚂蚁进行移动后他们的位置顺序是不会变的;第二,由于两只蚂蚁的速度都是一样的,所以当两个蚂蚁相遇掉头运动时,我们可以等价于两个蚂蚁都直接按照原来的方向运动。

根据点一我们先预处理蚂蚁编号与位置的关系,根据点二我们可以直接得出每个蚂蚁在时间T后的位置,然后根据预处理的关系的得出每个位置实际上是哪个蚂蚁。

我刚开始使用一个数组来标记T时间后木条儿上蚂蚁的位置,但这题木条儿好像很长(题目好像没有说范围,但是我一直RE),后来换了MAP。。。。。非常丑陋。。

其实再多思考一下就会发现一个位置上的蚂蚁最多不会超过两只,所以我们只要排序以后前后比较一下位置是否相等,就可以判断了。

#include
#include
#include
#include
#include
using namespace std;

const int N = 100010;

struct  Ant
{
	int num;
	int p;
	char op[100];
};

bool cmp1(Ant a, Ant b)
{
	return a.p < b.p;
}

Ant ant[N];

int main()
{
	int ncase;
	int nc = 1;
	int mb[N];      ///第i只蚂蚁距离左端的距离为第m[b]小
	int l, n, m;

	scanf("%d", &ncase);
	while(ncase --){
		map M;    ///M[i]表示距离木条儿左端i距离有M[i]只蚂蚁
		scanf("%d%d%d", &l, &n, &m);
		for(int i = 0; i < m; i ++){
			scanf("%d%s", &ant[i].p, ant[i].op);
			ant[i].num = i;
		}
		sort(ant, ant + m, cmp1);
		for(int i = 0; i < m; i ++){
			mb[ant[i].num] = i;
		}
		for(int i = 0; i < m; i ++){
			if(ant[i].op[0] == 'R'){
				ant[i].p = ant[i].p + n;
				M[ant[i].p] ++;     ///标记位置
			}
			else{
				ant[i].p = ant[i].p - n;
				if(ant[i].p < 0){
					//ant[i].p = -1;
					continue;
				}
				M[ant[i].p] ++;     ///标记位置
			}
		}
		sort(ant, ant + m, cmp1);
		printf("Case #%d:\n", nc ++);
		for(int i = 0; i < m; i ++){
			int t = mb[i];
			if(ant[t].p < 0 || ant[t].p > l){
				printf("Fell off\n");
			}
			else{
				printf("%d ", ant[t].p);
				if(M[ant[t].p] > 1){
					printf("Turning\n");
				}
				else{
					printf("%c\n", ant[t].op[0]);
				}
			}
		}
		printf("\n");
	}

	return 0;
}






你可能感兴趣的:(ACM,-,思维)