描述
一辆洒水车从原点出发,向 x 的正半轴工作,它每秒都会向前移动一个单位,每移动 s 秒,它就会向前喷洒长度为 t 的水,值的注意的是,当洒水车出发的那一刻,它会先洒一次水。举个例子,当 s = 4,t = 2 时,也就是洒水车每 4 秒就会向前洒一次长度为 2 的水,那么它会先在原点处向横坐标为 1 和 2 的两个点洒水,4 秒后,洒水车移动到了横坐标为 4 的点,然后向横坐标为 5 和 6 的两个点洒水,依次类推。现在罗少想知道,有多少个横坐标在区间 [L,R] 内的点被洒过水。
输入
第一行是两个正整数 s 和 t 含义如描述所述。(1 <= s,t <= 1e9)
然后是一个正整数 T 代表罗少询问的次数。(1 <= T <= 1000)
每次询问包含两个正整数 L 和 R 分别代表区间的左右端点。(1 <= L <= R <= 1e9)
输出
针对每次询问,回答区间 [L,R] 内,有多少个点被洒过水,然后换行。
分析:可以考虑包成一个函数,其目的是返回从1到a区间内洒过水的点数。
根据 s 和 t 的大小关系分成两种情况考虑:
1)当s<=t时,因为题意是每走 s 步,就向前面 t 格洒上水;又因为在原点的时候,会先向前面 t 格洒上一次水;因此若s<=t,除了原点之外的其他点全都洒过水。
2)当s>t时,再划分为两个情况:
①1<=a<=s,其中若a<=t,直接返回a的值;若a>t,返回 t 的值;
② a>s,定义两个整形变量:n与remainder。n用于计算1~a范围内有几个完整的 s(因为知道每s个点里一定有t个点被洒过水),而remainder(余数)在于计算剩下不足以凑齐s的点中有几个点是被洒过水的;
如果remainder<=t,remainder就是被洒过水的点的个数;
如果remainder>t,需要将remainder赋值为 t 。最后返回n*t+remainder即可。
Ps:计算[L,R]区间内符合题意的点数时,计算左边时,代入函数的值应为(L-1);而不是用函数分别计算到L,R的,最后相减+1;由于不能确定L点到底是不是洒过水的,这样的做法无疑是错误的。
最后附上代码如下:
#include<iostream>
using namespace std;
typedef long long ll;
ll f(ll s, ll t, ll a)
{
if (s <= t)
{
return a;
}
else//当s>t时,从1到a有多少被标记的点
{
if (a <= s)
{
if (a > t)//(t<a<=s)
{
return t;
}
else//(1<=a<=t)
{
return a;
}
}
else
{
ll n, remainder;
n = a / s;
remainder = a % s;
if (remainder > t)
{
remainder = t;
}
return n *t + remainder;
}
}
}
int main()
{
ll s, t, m;
cin >> s >> t >> m;
while (m--)
{
ll l, r;
cin >> l >> r;
ll a, b;
if (s <= t)
{
a = f(s, t, l-1);
b = f(s, t, r);
}
else
{
a = f(s, t, l-1);
b = f(s, t, r);
}
cout << b - a << endl;
}
return 0;
}
本身难度不大,但由于未能摆正心态仔细审视自己写的代码导致一再WA。。。
因此特地记录一下以后看到的时候提醒一下自己!@A@!