c++ 遥控赛车比赛(某地小学组真题,单层循环解决,内有彩蛋)

文章讲述了在一场青少年车辆模型比赛中,小A和小B的赛车如何通过记录速度和时间来计算他们的赛车交替成为第一名的次数。作者提供了一个基于代码的解决方案,展示了如何通过比较每个单位时间内两车行驶的路程来确定位置交替。
摘要由CSDN通过智能技术生成

1.题目描述 

9月27日下午,伴随着灰原哀的一声令下,一辆辆赛车呼啸而出,2021年鄞州区青少年车辆模型联赛暨TT01与雷虎遥控赛车比赛,正在激烈地进行着。跑在最前面的是小A同学和小B同学的赛车,两个同学的赛车你追我赶,难分胜负。灰原哀用DV记录下了整个过程。
小A同学和小B同学的赛车从同一个起点出发,并且他们的总用时一样。我们用“片段”法记录赛车的前进过程,例如,小A的赛车以1的速度运行2个单位时间,然后以4的速度运行1个单位时间。
灰原哀想知道,这两辆赛车交替成为第一名的次数。例如,如果一开始小B的车子领先,然后小A车子超越小B,那么这就是一次第一名位置的交替。如果一开始小B的车子领先,然后A与B一样快,并僵持一段时间,然后最终小A领先,那么这也就意味着第一名位置的交替,但是,如果直到比赛结束小A都没有取得领先,那么不算第一名位置的交替。
输入
第1行:两个整数用空格隔开,N和M(1<=N,M<=1000)
第2到1+N行:每一行包含一个小A的赛车跑的N段路程,由两个整数描述:第一个数表示速度和第二个数表示以该速度运行的时间(两个整数都在1到1000范围内)。
第2+N到1+N+M行:每一行包含一个小B的赛车跑的M段路程,由两个整数描述:第一个数表示速度和第二个数表示以该速度运行的时间(两个整数都在1到1000范围内)。
输出
一行:第一名位置的交替次数。
样例输入 Copy
4 3
1 2
4 1
1 1
2 10
2 3
1 2
3 9
样例输出 Copy
2

2.样例分析

真题老样子,先分析一遍样例:

输入说明:
小A的赛车以1的速度跑2单位的时间,然后以4的速度跑1单位的时间,然后以1的速度跑1单位的时间,最后以2的速度跑10单位的时间。
小B的赛车以2的速度运行3个单位的时间,然后以1的速度运行2个单位的时间,最后以3的速度运行9个单位的时间。
请注意,这两辆车的总用时一样,都是跑了14个单位的时间。
输出说明:
小B的赛车领先,直到时间t=3,当两辆赛车都经过了6个单位的距离后相遇,并一起跑了1个单位的时间。小A的赛车随后短暂领先(第一次第一名位置的交替),但不久t=7时就被小B的赛车超越(第二次第一名位置的交替)。最后小B的赛车赢得了比赛。

3.代码

直接上代码:

#include<bits/stdc++.h>
#define MX 1000000//时间最大是1000,n和m最大都为1000 1000 * 1000 = MX
#define NX 1000//n,m的最大
using namespace std;
int s1[MX + 10] = {0},s2[MX + 10] = {0};//s1用来存储每单位时间,A车走的路程;s2道理同上
int main()
{
	int n,m,i,j,av[NX + 10],at[NX + 10],bv[NX + 10],bt[NX + 10],p = -1;
    //由于可能在第一个A或B就领先对方,p用来判断
	cin >> n >> m;
	long long int cnt = 0,ans = 0,k1 = 1,t1 = 0,k2 = 1,t2 = 0;
	for (i = 1;i <= n;i++)
	{
		cin >> av[i] >> at[i];
	}
	for (i = 1;i <= m;i++)
	{
		cin >> bv[i] >> bt[i];
	}//读入,当然也可用结构体
	for (i = 1;i <= 1000000;i++)//遍历s1
	{
		if (k1 > n)
		{
			break;
		}
		s1[i] = s1[i - 1] + av[k1];//计算每个单位时间A车走的路程
		t1++;//at[]表示的是用av走的时间,t1计算用av[k1]走的时间
		if (t1 >= at[k1])//当用av[k1]速度走完了at[k1]时间时
		{
			k1++;
			t1 = 0;//更新
		}
	}
    //B车与A车道理相同
	for (i = 1;i <= 1000000;i++)
	{
		if (k2 > m)
		{
			break;
		}
		s2[i] = s2[i - 1] + bv[k2];
		t2++;
		if (t2 >= bt[k2])
		{
			k2++;
			t2 = 0;
		}
	}
	for (i = 1;i <= 1000000;i++)//注意题目中已经说过,总时间相同,所以1层循环即可(嘿嘿嘿)
	{
		if ((s1[i] > s2[i] && s1[i - 1] <= s2[i - 1]) || (s2[i] > s1[i] && s2[i - 1] <= s1[i - 1]))//A或B中有一个超过对方
	    {
	    	ans++;
	    	if (p == -1)//特判
	    	{
	    		p = i;
			}
		}
	}
	if (p == 1)//若在开始就领先
	{
		cout << ans - 1 << endl;//最开始的领先不算
	}
	else
	{
		cout << ans << endl;
	}
	return 0;
}

4.解题思路

我的方法仅是众多方法的一种啦(还可以用STL,队列deque,queue什么的)。应该还算通俗易懂。基本思路就是看看每个单位时间(用t表示,当然在程序中不是用t表示)A车与B车走的路程,当A车走过的路程比B车大,而且A车在(t - 1)单位时间时,所走的路程比B车小(或相等),ans++;B车同理。万分万分注意的是,最开始领先的不算!!!最开始领先的不算!!!最开始领先的不算!!!(重要的事情说三遍)

5.杂谈

这道题应该是2021年鄞州区比赛的一道题,含金量还算高(当然比不上CSP,NOIP,NOI)这样的。在当年4道题都拿到满分的可算是大神了(本人拿到了,虽然不是当年直接去考的,呵呵呵~)。

6.

-加上这个才算完美-

7.不不不,还有一个

  两张图片无关联哦!~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值