蓝桥杯官网原文:202420242024 个被报出的数是多少
一、方法1(秒杀型)
解题思路
通过观察发现,第奇数位个数是20的倍数,第偶数位个数是24的倍数。所以第202420242024个数
就是24的倍数,那我们直接除以2(判断是这个数是第几个24的倍数),然后再乘24就行。
也就是202420242024÷2×24=2429042904288
源代码
public class Main {
public static void main(String[] args) {
long no = 202420242024L;
doTest1(no);
}
static void doTest1(long num) {
System.out.println(num / 2 * 24);
}
}
二、方法2(普通归纳演绎性)
解题思路A
(1)在草稿纸枚举了前20个数。
第1-10个: 20 24 40 48 60 72 80 96 100 120。
第11-20个:140 144 160 168 180 192 200 216 220 240。
(2)发现从0到第10个数的间隔是20,4,16,8,12,12,8,16,4,20。发现从10到第20个数的间隔也是20,4,16,8,12,12,8,16,4,20。大胆推测十个数就是一个周期轮回。从0开始,每个周期内,十个数之间的间距(差值)分别是20,4,16,8,12,12,8,16,4,20。
(3)每个周期之间的间距为20+4+16+8+12+12+8+16+4+20,或者直接120(即120-0)
(4)第 202420242024 个报数为20242024202个周期(即202420242024/10),然后再加上4(即202420242024%10)。也就是202420242020/10*120=202429042904240,找它之后的四个能被20或24整除的数。
解题思路B
(1)在草稿纸枚举了前40个数得出来的
第1-10个: 20 24 40 48 60 72 80 96 100 120
第11-20个:140 144 160 168 180 192 200 216 220 240
第21-30个:260 264 280 288 300 312 320 336 340 360
第31-40个:380 384 400 408 420 432 440 456 460 480
(2)发现第10个数,第20个数,第30个数,第40个数......(每十个数为一轮)等等都是120的倍数,
(3)既然题目要求第202420242024个数,那我们不妨先求第202420242020个数,然后再往后再多求4个数就行。也就是202420242020/10*120=202429042904240,找它之后的四个能被20或24整除的数,也就是2429042904288
源代码
对于本方法,思路A和思路B异曲同工,代码本质上一样。因此,下面只给出一份源代码。
public class Main {
public static void main(String[] args) {
long no = 202420242024L;
doTest2(no);
}
static void doTest2(long num) {
long h = num / 10;
int low = (int) (num % 10);
long k = 0;
// 20+4+16+8+12+12+8+16+4+20;
long n = 120 - 0;
long m = h * n;
while (k < low) {
m = m + 4;
if (m % 20 == 0 || m % 24 == 0) {
k++;
}
}
System.out.println(m);
}
}
三、方法3(通用归纳演绎性)
解题思路
(1)在草稿纸枚举了前20个数。
第1-10个: 20 24 40 48 60 72 80 96 100 120。
第11-20个:140 144 160 168 180 192 200 216 220 240。
第21-30个:260 264 280 288 300 312 320 336 340 360
(2)发现从0到第10个数的间隔是20,4,16,8,12,12,8,16,4,20。发现从10到第20个数的间隔也是20,4,16,8,12,12,8,16,4,20。大胆推测十个数就是一个周期轮回。从0开始,每个周期内,十个数之间的间距(差值)分别是20,4,16,8,12,12,8,16,4,20。
同时注意到:第十个数120是20和24之间的最小公倍数,第二十个数240是最小公倍数120*2,第三十个数360是最小公倍数120*3,轮回周期就是最小公倍数
(3)用变量a代表20,变量b代表24,计算出他们最小公约数gcd和最小公倍数(既轮回周期step),以及周期内能被a或者b整除数的个数n
(4)第k 个报数,即为k/n个周期,然后再加上k%n个报数。也就是k/n*step,找它之后的k%n个能被a或b整除的数。
源代码
public class Main {
public static void main(String[] args) {
long k = 202420242024L;
doTest3(k, 20, 24);
// k = 20242024L;
// doTest3(k,20,24);
// doTest4(k,20,24);
// doTest3(k,20,28);
// doTest4(k,20,28);
}
static void doTest3(long num, int a, int b) {
// TODO Auto-generated method stub
int gcd = getGCD(a, b);
// 最小公倍数求解
int step = a / gcd * b;
//周期内被a和b整除数的个数
int n = count(0, step, a, b, gcd);
long h = num / n;
int low = (int) (num % n);
long k = 0;
long m = h * step;
while (k < low) {
m = m + 4;
if (m % 20 == 0 || m % 24 == 0) {
k++;
}
}
System.out.println(m);
}
static void doTest4(long num, int n1, int n2) {
// 暴力求解
long i = 1;
int count = 0;
while (true) {
i += 1;
if (i % n1 == 0 || i % n2 == 0) {
count++;
}
if (count == num) {
break;
}
}
System.out.println(i);
}
/*
* 寻找从start到end之间,能被a或b整除的数个数.如果公约数gcd小于1,则内部再根据a和b计算
*/
static int count(int start, int end, int a, int b, int gcd) {
long temp = start;
int count = 0;
if (gcd < 1) {
gcd = getGCD(a, b);
}
do {
temp += gcd;
if (temp % a == 0 || temp % b == 0) {
// System.out.println(temp);
count++;
}
} while (temp < end);
return count;
}
/*
* 求最小公约数
*/
static int getGCD(int a, int b) {
int min = a < b ? a : b;// 判断并取出两个数中小的数
for (int i = min; i >= 1; i--) { // 循环,从最小值开始,依次递减,直到i=1
if (a % i == 0 && b % i == 0) { // 当i能同时被A和B余尽时,返回i
return i;
}
}
return 1;
}
}
结束