Piotr's Ants UVA - 10881 (思维)

问题链接



问题描述:

一根长度为L的木棍上有n只蚂蚁,每只蚂蚁要么往左爬,要么往右爬,速度为1,,当两只蚂蚁相撞时,两者同时掉头,给出每只蚂蚁的初始位置和朝向,计算T秒之后每只蚂蚁的位置和朝向。


输入:第一行为测试样例的书目

  每个测试样例先输入一个n 代表n只蚂蚁

    随后n行 每行给出蚂蚁的初始位置和朝向


输出:求T秒后各个蚂蚁的位置和朝向 若已经掉落则输出Fell off  若刚好两只蚂蚁相遇则输出Turning


分析:

①不管什么时刻 蚂蚁的相对位置是不变的(可以自己想象一下,两只蚂蚁相遇后不可能穿过对方,所以相对位置不会改变)

②但是宏观上我们可以看做蚂蚁穿过对方继续行走


综上所述,蚂蚁终止时刻的位置是 初始位置 + T * d (d代表方向,-1向左 0 正在转向 1 向右)

那么求出这些终止位置,我们只需要排序,就能确定谁是谁了(因为相对顺序不变)


代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100000 + 5
using namespace std;

struct ant
{
	int id,position,direct;
	// -1 < 0 | 1 >	
	bool operator < (const ant& A) const
	{
		return this->position < A.position;
	}
};
const char sen[][15] = {"L","Turning","R"};
ant before[maxn];
ant after[maxn];
int order[maxn];
int main()
{
	int Case;
	scanf("%d",&Case);
	int cnt = 0;
	while(Case--)
	{
		int L,T,n;
		scanf("%d %d %d",&L,&T,&n);
		for(int i = 0;i<n;i++)			 
		{
			int t; char p;
			scanf("%d %c",&t,&p);
			ant a;
			a.id = i;
			a.position = t;
			a.direct = (p=='L' ? -1 : 1);
			before[i] = a;
			ant b;				//预处理出终止蚂蚁和初始蚂蚁 
			b.id = 0;
			b.position = t + T * (p == 'L' ? -1 : 1) ;
			b.direct = (p=='L' ? -1 : 1);
			after[i] = b;
		}
		sort(before,before+n);
		for(int i = 0;i<n;i++)
		{
			order[before[i].id] = i;		//初始蚂蚁的次序 
		}
		sort(after,after+n);		//得到终止序列 
		for(int i = 0;i<n-1;i++)
		{									//正在转向的蚂蚁 
			if(after[i].position == after[i+1].position) after[i].direct = after[i+1].direct = 0;
		}
		printf("Case #%d:\n",++cnt);
		for(int i = 0;i<n;i++)
		{
			int a = order[i];		//第i只蚂蚁 
			if(after[a].position<0 || after[a].position > L )
			printf("Fell off\n");  //掉落 
			else				//输出方向和位置 
			printf("%d %s\n",after[a].position,sen[after[a].direct + 1]);
		}
		printf("\n");
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值