牛客题解 | 最后一位

题目

题目链接

题解

题目难度:简单

知识点:数学问题,二分算法

分析:

针对本题,有两种方法,一种利用数学思想,较为直接粗暴的搜索;另一种方法可以利用二分法来解决

方法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&lt;=right){
          long mid = (left+right)/2;
          // 二分找到mid,求其sum值,与输入的sum值比较是否相等。
          long theSum = getSum(mid);
          if(theSum == sum){
            return mid;
          }else if(theSum &gt; sum){
            right = mid - 1;
          }else{
            left = mid + 1;
          }
        }
      return -1;
    }



    private static long getSum(long mid) {
      long res = 0;
      while(mid&gt;0){
        res+=mid;
        mid/=10;
      }
      return res;
    }
}

</count;i++){>

posted @ 2025-03-07 11:17  wangxiaoxiao  阅读(9)  评论(0)    收藏  举报