import java.util.*;
public class Main{public static void main(String[] args){Scanner in=new Scanner(System.in);int n=in.nextInt(),copy=n;// 取每一位上的数放入数组List<Integer> list=new ArrayList<>();while(n!=0){int res=n%10;list.add(0,res);n/=10;}// 转数组n=list.size();int[] arr=new int[n];for(int i=0;i<n;i++){arr[i]=list.get(i);}// 处理:ans表示多加了的数的和int index=n-1,ans=0;while(true){int cur=arr[index];if(cur>4){// //1.判断前面高位中是否有数字4int i=index-1;while(i>=0&&arr[i]!=4){i--;}if(i>=0){//在i处是4,多加的数是10的x次方int base=1;for(int j=i;j<index;j++){base*=10;}ans+=base;//i处的位值减1:表示第i个位次处理了一次,将位值减1,下同arr[i]--;}else{// 2.前面高位中没有4,多加的数为1ans++;//上一个非0更高位减1:如59变49i=index-1;while(i>=0&&arr[i]==0){i--;}//找不到,说明处理结束,下同if(i<0)break;arr[i]--;//从i到index的路程中的0位全部置为9:模仿借位for(int j=i+1;j<index;j++){arr[j]=9;}}}else{//向最近一个高位借位(该位必须不为0)int i=index-1;while(i>=0&&arr[i]==0){i--;}if(i<0)break;arr[i]--;// 中间的数全部置9(包括index)for(int j=i+1;j<=index;j++){arr[j]=9;} }}System.out.println(copy-ans);}
}
简要:每个数位从9到0均统计一遍,其中个位上只需统计1次。原数肯定不包含4,但在逐一借位时可能产生4,要单独处理.
如n=99
99: 多加了1, 高位降1,变为89,再判断
89: 多加了1, 高位降1,变为79
79: 多加了1, 高位降1,变为69
……
49: 从40-50都会被跳过,多加了10.
……
09:多加了1,高位无法再降,结束。
对于n=100,个位为0,显然没有跳过4,需要将其降到个位大于4的最大数:99,即借位。
当个位上的数小于4时,需要“借位”,即让上一个非0高位减1,个位的值变9.其实只要比4大就行,不影响结果。