记:洒水车

描述
一辆洒水车从原点出发,向 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@!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值