2023年蓝桥杯省赛——幸运数字

目录

[题目链接:0幸运数字 - 蓝桥云课 (lanqiao.cn)](#题目链接:0幸运数字 - 蓝桥云课 (lanqiao.cn))

解法

思路

高级思路

总结


题目链接:0幸运数字 - 蓝桥云课 (lanqiao.cn)

解法

首先是我写了差不多一个小时的解法,裂开了,为什么我如此废物

思路

寻找第2023个在二进制、八进制、十进制和十六进制表示下都为哈希德数的整数

在main函数中通过一个while循环来遍历所有的整数,直到找到第2023个满足条件的整数。position变量用于记录已经找到多少个满足条件的整数。

在每次循环中,首先通过调用getEachSum(i)函数计算整数i在十进制下各个位数之和。如果i不能被这个和整除,那么就继续检查下一个整数。

如果i能被这个和整除,那么就把i转换成二进制字符串,并计算字符串中所有字符(除去字符'0')的数量,这也就是二进制下各位之和。再检查i是否能被这个和整除,如果不能,那么就继续检查下一个整数。

接着,把i转换成八进制的形式,然后用getEachSum(octal)计算这个八进制数的各位之和,并检查i是否能被这个和整除,如果不能,那么就继续下一个整数。

再然后,把i转换成十六进制字符串,并计算字符串中所有字符对应的数值之和。这一步中,有一个try...catch结构,这是因为十六进制数包括0-9和a-f两部分,对于a-f,用字符的阿斯奇码值减去'87'来得到对应的数值。再检查i能否被这个和整除,如不能,继续下一个整数。

如果i能被所有这些和整除,那么就意味着i在二进制、八进制、十进制和十六进制下都是哈希德数,于是就把它放入数组arr中,并使position加一,然后继续检查下一个整数。

getEachSum函数的作用是计算一个十进制数各位数之和,如果输入是非十进制的数,那么必须先将其转换为十进制。

一直到找到第2023个满足条件的整数,然后结束循环,输出这个整数。

是不是很流畅但是写的太复杂了,然后我去看了看其他大佬的题解,就发现了另一个结题思路

java 复制代码
package src;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
//1:无需package
//2: 类名必须Main, 不可修改

public class Main {
 public static void main(String[] args) throws IOException {
     StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
     // 如果一个整数在二,八,十,十六进制下都可以被条件整除记录
     int position = 1;
     int i = 1;
     long res = -1;
     long[] arr = new long[2023];
     while (position <= 2023) {
    	long sum = getEachSum(i);
		boolean flag = true;
		// 判斷是否十进制符合
		if (i % sum != 0) {
			i++;
			continue;
		}
		// 判斷是否二进制符合
		String strBinary = Integer.toBinaryString(i);
		char[] binary = strBinary.toCharArray();
		sum = 0;
		for (char c : binary) {
			sum += c - 48;
		}
		if (i % sum != 0) {
			i++;
			continue;
		}
		
		// 判斷是否八进制符合
		long octal = Integer.parseInt(Integer.toOctalString(i));
		sum = getEachSum(octal);
		if (i % sum != 0) {
			i++;
			continue;
		}
		// 判斷是否十六进制符合  2a
		String strHex = Integer.toHexString(i);
		char[] strS = strHex.toCharArray();
		sum = 0;
		for (char c : strS) {
			try {
				sum += Integer.parseInt(c + "");
			} catch (Exception e) {
				// TODO: handle exception
				sum += c - 87;
			}
		}
		if (i % sum != 0) {
			i++;
			continue;
		}
		
		// 如果走到这里说明全部符合
		
		res = i;
		arr[position - 1] = res;
		position++;
		i++;
	}
     System.out.println(res);
 }
 
 public static long getEachSum(long num) {
	 long res = 0;
	while(num > 0) {
		long one = num % 10;
		res += one;
		num /= 10;
	}
	return res;
 }
}

通过这段不太聪明的代码之后就成功的跑出来了。


高级思路

main函数里首先,声明了一个计数变量cnt,设置初始值为0。接着,进入一个无限循环,每次循环都会将i(起始值为1)作为待检查的数字,

然后,调用check函数检查这个数字在二进制、八进制、十进制和十六进制(也就是Mod 2, 8, 10 和 16)中是否都是哈希德数。 如果这个数字在所有这些进制下都是哈希德数,那么将计数变量cnt加1。 然后检查cnt是否等于2023,如果是,那么就输出当前的数字i并退出循环。如果不是,那么就将i增加1,并开始下一个循环,继续检查下一个数字。

重要的,高级的来哦了,check函数是用于检查一个数字在给定进制下是否是哈希德数的函数。它接受两个参数,x代表待检查的数字,mod代表要将x转换成哪种进制。函数内部,首先复制x的值给n保存,然后通过一个循环,计算转换为mod进制下的各位数值和ans。如果n可以被ans整除,那么就返回真(即该数在给定进制下是哈希德数),否则返回假。

我来特别解释一下check函数

check函数中,while循环是用来计算一个给定整数x在特定进制mod下所有位上数字之和的。

整个流程是这样的:

  1. 初始化ans为0,这个变量用来存储x在特定进制下所有位上数字之和。

  2. 进入while循环,只要x大于0,就一直执行循环。

  3. 在每次循环中,xmod取余(即 x % mod),这相当于得到xmod进制下的最低位。根据余数定理和我们的进制制度,当一个数对某个进制进行取余操作时,得到的余数就是该数在这种进制下的最低位。(大家可以回想一下自己求十进制数的个位的时候是不是就是这个操作

  4. 把取得的最低位加到ans里,ans在循环过程中始终记录了xmod进制下所有已经处理过的位的和。

  5. 然后用 x除以mod(即 x / mod),结果赋值给x,这相当于把xmod进制下的最低位去掉。再次运用余数定理和我们的进制制度,当一个数被某个进制的数除时,结果就是这个数在这种进制下去掉最低位的部分。

  6. 这个循环反复执行,直到x小于等于0,也就是我们说的x已经没有剩下位数要处理。

所以这个while循环的作用就是,将一个给定的数x在给定的进制mod下的所有位上的数字全部加起来,结果存放在ans中。

我只能说天才

所以说,这段代码的功能就是找出第2023个在2、8、10、16进制下都是哈希德数的数字。

java 复制代码
public class Main {
    public static void main(String[] args) {
      int cnt = 0;
      for(int i=1; ; i++){
          if(check(i, 2) && check(i, 8) && check(i, 10) && check(i, 16)) cnt++;
          if(cnt == 2023){
             System.out.println(i);
             break;
          }
      }
      
    }

    //判断是否为mod进制下的哈沙德数
    public static boolean check(int x, int mod){
      int n = x;
      int ans = 0;
      while(x>0){
        ans = ans+ x%mod;
        x /= mod;
      }
      return n%ans==0;
    }
}

总结

大佬就是大佬,蓝桥杯四个小时,这道题我写了一个小时,我已经废了

再见

相关推荐
Alicx.8 小时前
dfs由易到难
算法·蓝桥杯·宽度优先
心软小念8 小时前
金三银四,全网最详细的软件测试面试题总结
软件测试·面试·职场和发展
软件测试媛10 小时前
软件测试常见的面试题(46道)
功能测试·面试·职场和发展
IronMurphy11 小时前
【算法三十一】46. 全排列
算法·leetcode·职场和发展
红云梦13 小时前
简历投了 100 份没回音?我给面试平台加了个“简历雷达“
人工智能·面试·职场和发展
studyForMokey16 小时前
【Android面试】Gradle专题
android·面试·职场和发展
编程一生18 小时前
面试问到的那些技术细节
面试·职场和发展
软件测试慧姐19 小时前
面试中常问的软件测试面试题
面试·职场和发展
蒸汽求职19 小时前
【蒸汽教育求职干货】OPT只剩3个月还没找到工作,怎么办?——留学生IT求职的“紧急预案”
人工智能·经验分享·面试·职场和发展·美国求职
蒸汽求职19 小时前
【蒸汽教育求职分享】美国IT面试的Behavioral Question:STAR法则人人都知道,但90%的人用错了
人工智能·面试·职场和发展·github·求职招聘·留学生求职