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

目录

题目链接: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个满足条件的整数,然后结束循环,输出这个整数。

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

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进制下都是哈希德数的数字。

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;
    }
}

总结

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

再见

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WenJGo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值