大于或等于x的等差数是多少?
提示:京东20220416笔试题
京东笔试的风格:
30个选择题,各个都难,要求基础贼深,这个需要去百度的(2分一个)=60分
2个算法题(20分一个)=40分 算法题是真的难!!!平时不好好练习准备,临场啥也做不出来。
题目
题目1–小明觉得“等差数”是一类非常妙的数字,这类数字定义如下:
是十进制下的数字,
设这个数字有n位,di表示该数从低位到高位的第i位,则由d2-d1=d3-d2=…=dn-dn-1.特别地,n=1也是等差数。
例如:10,2345,5432,111,9,0,86420,94是等差数,而233,114514,2356,1325,124则不是等差数。
小明随手写了一个数字x,他想知道,大于或等于x的最小的等差数是多少?
输入:第一行一个整数T,表示有T组数据,每一组数据,输入一行一个非负整数x。0<=x<10^17,1<=T<=100;
输出:对于每一组数据,输出一行一个十进制数,表示答案。
样例输入:
5
100
0
152
233
212
输出:
111
0
159
234
222
一、审题
示例:互联网大厂的题目输入描述和输出描述与样例就是审题细节,讲得很清楚。
二、解题
考试当时我完全没有思路,所以算法题一个都不会
后来在牛客网上见到一个大佬的解法,觉得很有道理:
第一题思路:
称等差数前一位减后一位的差为位差,所有等差数的位差都在 [-9,9] ,如果确定了一个等差数的位差、任意一位的数字和这个数的长度,就可以确定这个数。
如等差数首位为8,长度为4,位差为-2,则这个数为8642
输入的数字是a,要找大于等于这个数的等差数b
首先可以b的最高位一定是大于或等于s的(我理解这个s就是a的最高位),且长度等于a(不管a是什么,总可以找到999…9这样的和a等长的等差数)【这里很关键,不管如何,b一定与a等长的,大不了1变2,变变变,到最高位9999…9这样的数】
对于b的每一个最高位s,往后每一位怎么取值?
令b最高位等于a最高位s,位差从-9到9开始遍历(首位相同时位差越小这个数就越小),
每次同一个等差,从高位到低位,把b的前面一位+d作为b本位的值,然后看合法与否?直到找到一个合法的等差数就是答案。
不合法的情况:
- 某一位的数字小于0或大于9 【这有用,因为往后面找,一旦数字小于0,就违规,或者超过9,那就要重新用一个d】
- 数值小于a
关键点
如果找不到合法的等差数,尝试下一种位差d;
如果所有的位差到了9还是不合法,只能令b的最高位加1再重复上面的过程!!【也即让最外面一层for循环,尝试b的最高位从a的最高位s–9走一遍】
注意,实际调试代码的时候,可能会遇到11111这种,d0,判断到N-1位时,都能满足所有d0,那就是它,不需要往上+1了。
还会遇到一个特殊情况,比如212这种,找到221了,那前面d=0,但是最后这个1
代码:
public static class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
int T = in.nextInt();
while (T != 0){
process();
T--;
}
}
public static void process(){
//读一个数,干一次,输出一个结果
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
String str = in.next();
//找>=x的等差数
//数为2位,1位原数就是
int N = str.length();
if (N <= 2) {
System.out.println(str);
return;
}
//至少3位数
char[] arr = str.toCharArray();
int[] ans = new int[N];//最终长度也是相同的,大不了来一个全数字一样的数999...999
//int d = arr[0] - arr[1];//高位-地位,永远在-9--9之间
for (int i = 0; i <= 9; i++) {
//枚举最高位需要在arr基础上增加的数字,最多99999
ans[0] = arr[i] - '0' + i;
//遍历ans的后面每一位,值是前面值+d,d取-9--9之间
for (int d = -9; d <= 9; d++) {
String tmp = String.valueOf(ans[0]);//记录目前构成的新数字为字符串
for (int j = 1; j < N; j++) {
ans[j] = ans[j - 1] + d;//构成等差
tmp += String.valueOf(ans[j]);
if (ans[j] < 0 && ans[j] > 9 ||
(j == N - 1 && tmp.compareTo(str) < 0)) {
break;//不合法,重新尝试下一个等差d
}else if (j == N - 1 && tmp.compareTo(str) >= 0){
if (d == 0 && ans[N - 1] != ans[N - 2]){
//2221这种
ans[N - 1] = ans[N - 2];//构成等差22222
tmp = tmp.substring(0, N-1) + String.valueOf(ans[N-1]);//截取,加
System.out.println(tmp);
return;
}else if (d == 0 && ans[N - 1] == ans[N - 2]){
System.out.println(tmp);//d=0的话,111这种
return;
}
//
if (d != 0 ){
System.out.println(tmp);//d不是0的话,必然是1234,5432这种
return;
}
}
}
}
}
return;
}
总结
提示:重要经验:
1)基础不牢,地动山摇!!!好好练习根基的算法代码,关于数字这方面的题目,多积累
2)每次遇到不会的题,找大佬的思路,学,自己coding,练习。