蓝书 第一章 例题5 蚂蚁 uva

Posted 行码棋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝书 第一章 例题5 蚂蚁 uva相关的知识,希望对你有一定的参考价值。

题目:

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

输入:
输入的第一行为数据组数。每组数据的第一行为3个正整数L, T,n(0≤n≤10 000);以下n行每行描述一只蚂蚁的初始位置,其中,整数x为蚂蚁距离木棍左端的距离(单位:厘米),字母表示初始朝向(L表示朝左,R表示朝右)。

输出:
对于每组数据,输出n行,按输入顺序输出每只蚂蚁的位置和朝向(Turning表示正在碰撞)。在第T秒之前已经掉下木棍的蚂蚁(正好爬到木棍边缘的不算)输出Fell off。

 这是一道思维题

  • 首先明白一点:蚂蚁的相对顺序不变

    什么意思呢?

    因为每个蚂蚁总是之间来回碰撞,实际并没有穿过对方,碰之后就转向,原来蚂蚁在数轴上排在第几位,现在还是排在第几位。

     
  • 然后:可以这样思考:假设每个蚂蚁碰撞后穿过了对方,那么蚂蚁的位置可以计算出来(因为是直线一直跑没有转向),这样蚂蚁的位置就很容易算出来。

    但是在该位置上到底是哪个蚂蚁就不知道了,我们就需要弄清这只蚂蚁是哪个?
     

思路:

  • 首先对每个蚂蚁开一个结构体,将初始状态和最终状态分别存一个结构体数组。初始状态的结构体按位置从小到大排序。
  • 我们使用order[i]数组表示第i个输入的蚂蚁的位置的相对大小,如果order[i]表示的数小,说明第i个输入的蚂蚁的位置在数轴的左边。
  • 如何获取蚂蚁的方向呢?

    因为蚂蚁的相对位置是不变的。

    我们之前假设蚂蚁互相穿过去,他们的方向是不变的,可以发现这正好是碰撞后实际蚂蚁的朝向(实际指的是蚂蚁碰撞后转向),所以可以正好利用这一点,直接输出当前蚂蚁朝的方向就行。
  • 之前蚂蚁的状态用来求order数组,然后得出最终状态的所有蚂蚁的位置(此时是假设蚂蚁互相穿过去),然后按位置进行排序,如果位置相同说明碰撞,记d=0。数轴上从前往后的蚂蚁即为最终的蚂蚁的位置。
  • 只要记录输入蚂蚁的顺序,根据输入的顺序就输出对应的位置和转向就可以了。

代码技巧:

  • 结构体强制转换
  • 记录输入的顺序
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e4+5;
struct node
{
    //d=0 :Turning  ,1:R  0:L
	int id;int p;int d;//输入的顺序  位置  朝向 
	bool operator < (const node&a)const
	{
		return p<a.p; 
	}
}b[N],a[N];
string s[3] = {"L","Turning","R"};
int order[N];

int main()
{
	int _;
	cin>>_;
	for(int k=1;k<=_;k++)
	{
		cout<<"Case #"<<k<<":\\n";
		int L,T,n;
		cin>>L>>T>>n;
		for(int i=1;i<=n;i++)
		{
			int p,d;
			char c;
			cin>>p>>c;
			d = (c=='L') ? -1 : 1; 
			b[i] = (node){i,p,d};
			a[i] = (node){0,p+T*d,d};
		}
		
		sort(b+1,b+1+n);
		for(int i=1;i<=n;i++)//获取order数组
			order[b[i].id] = i;//按输入顺序求在的位置等级,小的话在前面,否则在后面 
		
		sort(a+1,a+1+n);
		for(int i=1;i<n;i++)
		{
//			cout<<a[i].p<<" "<<a[i].d<<'\\n';
			if(a[i].p==a[i+1].p){
//				cout<<a[i].p<<" "<<a[i+1].p<<'\\n';
				a[i].d=a[i+1].d=0;
			} 
		}
//		for(int i=1;i<=n;i++)cout<<order[i]<<" ";
//		cout<<'\\n';
		for(int i=1;i<=n;i++)
		{
			int temp = order[i];//获取第i个输入的蚂蚁相对位置 
			if(a[temp].p<0||a[temp].p>L) cout<<"Fell off\\n";
			else cout<<a[temp].p<<" "<<s[a[temp].d+1]<<"\\n";
		}
		cout<<"\\n";
	}
	
	return 0;
 }
 /* 
2
10 1 4
1 R
5 R
3 L
10 R
10 2 3
4 R
5 L
8 R
*/

以上是关于蓝书 第一章 例题5 蚂蚁 uva的主要内容,如果未能解决你的问题,请参考以下文章

蓝书 第一章 例题2 突击战

蓝书第一章 例题3 分金币

蓝书 第一章 例题1 勇者斗恶龙

蓝书 第一章 例题14 填充正方形

《通信原理》复习笔记1----第一章绪论相关例题

uva1352 Colored Cubes LA3401