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.不不不,还有一个
两张图片无关联哦!~