☀(day41:C1)
目录
📝题目:
在海军节开幕式上,有A,B,C 三艘军舰要同时开始后鸣放礼炮各21响,已知A舰每隔5s放一次。
B舰每隔6s放一次,C舰每隔7s放一次。假设各炮手对时间掌握的非常准确,请编程计算观众
总共可以听到几次炮响。
🚩题目分析:
计算观众可以听到的炮声不就是21x3 = 63吗?
千万别这么算,因为三艘军舰鸣炮的间隔不同,所以会有同时鸣炮的情况,这时候观众只会听到一声炮响。所以我们需要做的就是围绕同时鸣炮的情况找出观众可以听到的炮声。
💡解题思路:
通过上面的分析我们可以直接找出三艘军舰鸣炮鸣炮的时间,然后判断三艘军舰是否在同一时间鸣炮,或者是其中两艘鸣炮时间是否相同。进而判断观众是否听到炮声。
怎么找出鸣炮的时刻呢?
我们可以规定同时开始鸣炮的时间0时刻,那么A军舰鸣炮要经过5秒,也就是再第5秒的时候鸣炮,那么A军舰第二次鸣炮有过5秒,也就是再低10秒的时候鸣炮,以此类推。
假设此时时间为a,那么我们就有
如果a%5 == 0则此时A军舰鸣炮
如果a%5 != 0 那么此时A军舰不鸣炮
B、C军舰也是如此。
接着我们判断三艘军舰的鸣炮情况。
(1表示鸣炮,0表示不鸣炮)
总共有以下8种情况
A B C
1 1 1 ABC同时鸣炮,听到1声跑响
1 1 0 AB同时鸣炮,听到1声跑响
1 0 1 AC同时鸣炮,听到1声跑响
0 1 1 BC同时鸣炮,听到1声跑响
1 0 0 只有A鸣炮,听到1声炮响
0 1 0 只有B鸣炮,听到1声炮响
0 0 1 只有C鸣炮,听到1声炮响
0 0 0 没有军舰鸣炮,听不到炮响
可以看到,除了最后一种情况,其他情况都只会听到一声炮响
🌈代码实现
# include <stdio.h>
main()
{
int a, b, c;
int number;
int flaga, flagb, flagc;
a = b = c = 0;
number = 0;
while (c <= 21*7)
{
if (a <= 21*5)
{
a += 1;
if (a % 5 == 0)
flaga = 1;
else
flaga = 0;
}
if (b <= 21*6)
{
b += 1;
if (b % 6 == 0)
flagb = 1;
else
flagb = 0;
}
if (c <= 21*7)
{
c += 1;
if (c % 7 == 0)
flagc = 1;
else
flagc = 0;
}
if (flaga + flagb + flagc != 0)
number += 1;
}
printf("观众可以听见%d声礼炮\n", number);
}
✏代码注释
# include <stdio.h>
main()
{
// 初始化变量和标记值flaga~c
int a, b, c;
int number;
int flaga, flagb, flagc;
a = b = c = 0;
number = 0;
// ABC三艘军舰放完礼炮各需要5*21秒,6*21秒,7*21秒
while (c <= 21*7) // 因为c不断增1且到达21*7所需时间最晚,所以做循环结束条件
{
if (a <= 21*5)
{
a += 1;
if (a % 5 == 0)
flaga = 1; // flaga标记当前是否是鸣炮时刻
else
flaga = 0;
}
if (b <= 21*6)
{
b += 1;
if (b % 6 == 0)
flagb = 1;
else
flagb = 0;
}
if (c <= 21*7)
{
c += 1;
if (c % 7 == 0)
flagc = 1;
else
flagc = 0;
}
if (flaga + flagb + flagc != 0) // 可以听到一次炮声,计数变量+1
number += 1;
}
printf("观众可以听见%d声礼炮\n", number);
}
注意到a,b,c都是从0开始并不断增1,那么我们可以使用一个同一变量来表示。(比如用i代替a,b,c看个人习惯)
🌈代码优化
#include<stdio.h>
main()
{
int number, i;
number = 0;
for(i = 0; i < 21*7 ; i++)
{
if(i % 5 == 0 && i <= 21*5)
{
number++;
continue;
}
if(i % 6 == 0 && i <= 21 * 6)
{
number++;
continue;
}
if(i % 7 == 0)
{
number++;
}
}
printf("观众可以听见%d声礼炮\n", number);
}
由于将a,b,c合并为i后,i再递增过程中会同时满足if (a <= 21*5),if (b <= 21*6),if (c <= 21*7)这三个条件,且if (a <= 21*5),if (b <= 21*6)会先于if (c <= 21*7)结束。
因为结束时A,B正好打满21发,此时flag的值为1,那么当A,B鸣炮结束后有
A B C
1 1 ?
1 1 ?
: : ?
: : ?
1 1 ?
会增大结果数,所以不使用标记值,直接使用continue分步计算三艘军舰鸣炮数。
如果三艘或两艘军舰鸣炮时刻相同,(如i%5 = i%6 = 0)那么由于continue,只会有一个if条件被执行,也就是说number只会+1,符合同时鸣炮只听到一声的实际情况。
今天就到这,明天见。🚀
❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄end❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄