牛客题解 | 最后一位
题目
题解
题目难度:简单
知识点:数学问题,二分算法
分析:
针对本题,有两种方法,一种利用数学思想,较为直接粗暴的搜索;另一种方法可以利用二分法来解决
方法1:
针对本题,第一想法是通过暴力的方法利用数学思路解答,给出sum的值求原值x(如果存在则为x,否则x=-1),那么sum = x+(1/10)x+(1/100)x+…。以例子sum= 564为例计算,x≈508,与真实结果509相差很少,可以通过从508开始往后展开n个元素的搜索,这样也可以在一定程度上减少搜索范围。因为sum的范围在[1, 10^18],所以要适当扩大搜索范围,在这个数据范围中n取100。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long sum = sc.nextLong();
// 1. 暴力数学搜索法
System.out.println(mathSolve(sum));
}
private static long mathSolve(long sum) {
// 统计位数
int count = 0;
long tmp = sum;
while(tmp>0){
count++;
tmp/=10;
}
//统计除数
double chu = 0;
for(int i=0;i<count;i++){ chu +="1" math.pow(10, i); 1+0.1+0.01+... } 获取第一个搜索数 long begin="(long)" (sum chu); 开始搜索 res="search(sum,begin);" return res; private static search(long sum, begin) { for(long i="begin;" i<begin+100;i++){ tmp="i;" sum2="0;" while (tmp> 0) {
sum2 += tmp;
tmp /= 10;
}
if (sum2 - sum ==0) {
return i ;
}
}
return -1;
}
}
方法2:
利用二分思想解决问题:设置左右两个指针left和right,sum值一定大于要求的真实值,所以这两个指针可以分别指向1和输入的sum,找到中间mid值,求mid值对应的总和’sum’进行比较。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long sum = sc.nextLong();
// 2. 利用二分查找的方法
System.out.println(BineraySearchSolve(sum));
}
private static long BineraySearchSolve(long sum) {
long tmp = sum;
long left = 0 ;
long right = sum;
while(left<=right){
long mid = (left+right)/2;
// 二分找到mid,求其sum值,与输入的sum值比较是否相等。
long theSum = getSum(mid);
if(theSum == sum){
return mid;
}else if(theSum > sum){
right = mid - 1;
}else{
left = mid + 1;
}
}
return -1;
}
private static long getSum(long mid) {
long res = 0;
while(mid>0){
res+=mid;
mid/=10;
}
return res;
}
}
</count;i++){>

浙公网安备 33010602011771号