【UVa10881 Piotr's Ants】数学 | 思维 | STL | E

8 篇文章 0 订阅
1 篇文章 0 订阅

近来感觉脑袋有点抽,做几道思维题活动活动…

【UVa10881】Piotr’s Ants

Time limit: 3.000 seconds

Tags:数学 思维

题目描述

给定一根长为 L   c m L\ cm L cm 的木棍和 n n n 只蚂蚁在初始时刻距木棍左端点的距离以及初始朝向( L L L 表示向左, R R R 表示向右)

蚂蚁运动速度为 1   c m / s 1\ cm/s 1 cm/s,要输出 T T T 秒后各蚂蚁的情况(蚂蚁相碰的瞬间速度反向)



输入

T T T 组。第一行输入组数 T T T

对于每组数据,包含若干行,第一行三个整数 L , T , n L,T,n L,T,n,分别代表木棍长度、持续时间和蚂蚁数目。

接下来 n n n 行,每行一个整数和一个字符(字符仅限 ′ L ′ 'L' L ′ R ′ 'R' R),表示该蚂蚁距木棍左端的位置和朝向

范围: 0 ≤ n ≤ 10000 0 \le n \le 10000 0n10000。(没给 L L L T T T 的范围)



输出

对于每组输入,首先输出一行 C a s e # n Case\# n Case#n n n n 是数据组号,从 1 1 1开始)

然后输出每只蚂蚁的状态(要求安照输入次序输出,而不是按照最终位置输出)

每只蚂蚁的状态输出一行:

  • 如果该蚂蚁脱离了木棍(超出左端或右端),输出 F e l l   o f f Fell\ off Fell off
  • 否则,先输出蚂蚁距左端的位置,再输出其朝向情况(朝左是 L L L,朝右是 R R R,正在发生碰撞是 T u r n i n g Turning Turning



输入样例

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



分析

e m m m . . emmm.. emmm.. 居然没有给 T T T L L L 的范围啊!所以这道题 直接暴力模拟即可 需要开动一下小脑筋。

在脑子里稍微想象一下这个场景。其实蚂蚁相碰时瞬间速度反向是一个很特殊的条件。就好像蚂蚁直接互相 “穿过” 了一样。但是又不完全是这样,因为题目要求输出时按照输入次序输出,所以蚂蚁们不是等价的,程序代码需要认得,或者说记住每只蚂蚁。

值得注意的是,蚂蚁们不管怎么相碰,他们的相对位置是不变的(任选一只蚂蚁,任意时刻后,其永远在其右的蚂蚁们的左侧,永远在其左的蚂蚁们的右侧),所以依靠这个就能在 T T T 秒后根据相对位置顺序辨别每只蚂蚁的身份,从而给出正确的输出。

这样代码里面的各种来回映射一定不要弄混淆了。注意写代码的时候要好好取变量名!


时间复杂度:

排序 + 遍历, O ( n log ⁡ n ) O(n\log n) O(nlogn)



AC代码

#include <stdio.h>
#include <string.h>
#include <algorithm>

#define LL long long
#define sc(x) {register char _c=getchar(),_v=1;for(x=0;_c<48||_c>57;_c=getchar())if(_c==45)_v=-1;for(;_c>=48&&_c<=57;x=(x<<1)+(x<<3)+_c-48,_c=getchar());x*=_v;}
#define se(x) {register char _c=getchar(),_v=1;for(x=0;_c<48||_c>57;_c=getchar())if(_c==45)_v=-1;else if(_c==-1)return 0;for(;_c>=48&&_c<=57;x=(x<<1)+(x<<3)+_c-48,_c=getchar());x*=_v;}
#define PC putchar
template<typename T>void PRT(const T a){if(a<0){PC(45),PRT(-a);return;}if(a>=10)PRT(a/10);PC(a%10+48);}
template<typename T>void UPRT(const T a){if(a>=10)UPRT(a/10);PC(a%10+48);}

constexpr int MN(1e4 + 7);

enum State
{
    L, R, M, O
};

struct Node
{
	State sta;
	int id;
	int x;

	inline bool operator <(const Node &o) const
	{
		return this->x < o.x;
	}
} a[MN];

int id_to_rank[MN];

int main()
{
	int T;
	sc(T)
	for (int cas=1; cas<=T; ++cas)
	{
		int len, t, n;
		char dir;
		sc(len)sc(t)sc(n)

		for (int id=0; id<n; ++id)
		{
			sc(a[id].x)
			scanf("%c", &dir);
			a[id].sta = (dir == 'L' ? L : R);
			a[id].id = id;
		}

		std::sort(a, a+n);

		for (int i=0; i<n; ++i)
		{
			id_to_rank[a[i].id] = i;

			if (a[i].sta == L)
			{
				a[i].x -= t;
				if (a[i].x < 0)
					a[i].sta = O;
			}
			else
			{
				a[i].x += t;
				if (a[i].x > len)
					a[i].sta = O;
			}
		}

		std::sort(a, a+n);

		for (int i=0; i<n; ++i)
		{
			if (i>0 && a[i-1].x==a[i].x || i<n && a[i+1].x==a[i].x)
				a[i].sta = M;
		}

		printf("Case #%d:\n", cas);
		for (int i=0; i<n; ++i)
		{
			const Node & now = a[id_to_rank[i]];
			switch (now.sta)
			{
				case L:
					PRT(now.x), PC(32), PC('L'), PC(10);
					break;
				case R:
					PRT(now.x), PC(32), PC('R'), PC(10);
					break;
				case O:
					puts("Fell off");
					break;
				case M:
					PRT(now.x), PC(32), puts("Turning");
					break;
			}
		}

		PC(10);
	}

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值