记录10
#include <bits/stdc++.h>
using namespace std;
bool f(int d1,int d2,int n){
int t=n%(d1+d2);
if(t<=d1&&t!=0) return true;
else return false;
}
int main() {
int a,b,c,d,n;
cin>>a>>b>>c>>d;
for(int i=1;i<=3;i++){
cin>>n;
bool x1=f(a,b,n);
bool x2=f(c,d,n);
int x=x1+x2;
if(x==2) cout<<"both";
else if(x==1) cout<<"one";
else cout<<"none";
cout<<endl;
}
return 0;
}
突破点
其中一条狗会先暴躁 a 分钟,然后安静 b 分钟,而另一条狗则会先暴躁 c 分钟,然后安静 d 分钟。这两条狗在一天中会无限地重复上述行为。
所谓“无限地重复”,其本质就是有迹可循,像两个闹钟一样,响铃一会就自己关闭了
狗子处于 发癫-休息 的循环周期中
思路
- 两条狗的行为一样,只是参数不同,可用一个函数来模拟
- 三个工人挨个进行判断
狗子规律性地发癫跟休息,所以只需要判断工人来的时候,是不是在其发癫时刻就行
规律性的区间判断,可以使用取余%,取余的本质就是一种循环,在循环队列中有更明显的体现
文章的补充部分来解释下取余操作的本质是一种规律性的循环
代码简析
bool f(int d1,int d2,int n){
int t=n%(d1+d2);
if(t<=d1&&t!=0) return true;
else return false;
}
d1狗子发癫时刻,d2狗子休息时刻,n为工人来的时刻
d1+d2 代表狗子在 发癫-休息 的循环周期
t代表目前狗子在 发癫-休息 这个循环周期的什么时刻
if(t<=d1&&t!=0)这个条件判断代表狗子处于发癫状态
注意:
对于全部的测试点,保证 1≤a,b,c,d,p,m,g<103。
数据是从1开始的
t=n%(d1+d2)代表狗子循环的周期,周期的尾巴是t=0此时是休息
if(t<=d1&&t!=0)这个条件判断代表狗子处于发癫状态
例子:
f(2,3,3) //狗子在1到2时刻发癫,3的时候休息,工人在3的时候来了、
此时t=3%(2+3) 即t=3,也就是狗子处于休息时刻
t的范围:1,2,3,4,0
1,2是狗子发癫
3,4,0是休息
提醒:0的时候就是5或者5的倍数,此时处于狗子 发癫-休息 周期的尾巴,还在休息
bool x1=f(a,b,n);
bool x2=f(c,d,n);
int x=x1+x2;
因为f函数是bool类型,所以用bool类型来接收
注:bool类型在进行运算的时候,真为1,假为0
补充
取余操作(Modulo Operation)的本质确实是一种规律性的循环。这种规律性主要体现在取余操作的结果总是周期性地重复。
1. 取余操作的定义
取余操作
a % b
的结果是a
除以b
的余数。数学上,可以表示为: a=b×q+r 其中:
a 是被除数。
b 是除数。
q 是商。
r 是余数,满足 0≤r<b。
2. 规律性的循环
取余操作的结果总是周期性地重复,因为余数的范围是固定的。具体来说,对于任何整数 a 和正整数 b,余数 r 的范围是 0 到 b−1。
示例1:时钟问题
时钟是一个很好的例子,它展示了取余操作的周期性。假设现在是11点,再过2小时是1点。这是因为: (11+2)mod12=1
示例2:数组索引
在数组中,取余操作可以用来实现循环索引。假设有一个长度为5的数组,索引从0到4。如果当前索引是4,再往后移一位,索引应该是0。这是因为: (4+1)mod5=0
3. 数学解释
取余操作的周期性可以通过模运算的性质来解释。对于任何整数 a 和正整数 b,余数 r 满足: r=a mod b 其中 r 的范围是 0 到 b−1。
示例3:周期性重复
假设 b=5,取余操作的结果会周期性地重复:
0mod5=0
1mod5=1
2mod5=2
3mod5=3
4mod5=4
5mod5=0
6mod5=1
7mod5=2
8mod5=3
9mod5=4
10mod5=0
可以看到,每5个数,结果就会重复一次。
4. 应用
取余操作的周期性在许多实际应用中非常有用,例如:
时钟问题:计算时间的加法和减法。
数组索引:实现循环数组,如循环队列。
哈希表:计算哈希值,确保哈希值在表的范围内。
周期性任务:调度周期性任务,如定时器。
5. 代码示例
以下是一个简单的C++代码示例,展示取余操作的周期性:
#include <iostream> using namespace std; int main() { int b = 5; for (int a = 0; a < 15; a++) { cout << a << " % " << b << " = " << a % b << endl; } return 0; }
输出结果
0 % 5 = 0 1 % 5 = 1 2 % 5 = 2 3 % 5 = 3 4 % 5 = 4 5 % 5 = 0 6 % 5 = 1 7 % 5 = 2 8 % 5 = 3 9 % 5 = 4 10 % 5 = 0 11 % 5 = 1 12 % 5 = 2 13 % 5 = 3 14 % 5 = 4
总结
取余操作的本质是一种规律性的循环,因为余数的范围是固定的。这种周期性在许多实际应用中非常有用,例如时钟问题、数组索引、哈希表和周期性任务。