A Broken Calculator 最详细的解题报告

题目来源:A Broken Calculator

题目如下(链接有可能无法访问):

A Broken Calculator


Time limit : 2sec / Stack limit : 256MB / Memory limit : 256MB

Problem

Dave's calculator is broken. His calculator halts when put more than K kinds of number.

Dave wants to input an integer A, but if he put this number correctly the calculator might halt. Instead, he inputs the closest integer that won't halts the calculator.

Output the difference between Dave's input and the integer A.


Input

The input will be given in the following format from the Standard Input.

A K
  • On the first line, you will be given the integer A(1≦A≦1015), the integer Dave wants to input, followed by a space andK(1≦K≦10), the kinds of number his calculator can recognize.

Acheivements and Points

  • When you pass every test case where 1≦A≦100,000, you will be awarded 30 points.
  • In addition, if you pass all the rest test cases you will be awarded 70 more points.

Output

Output the minimum difference between Dave's input and the integer A in one line. Make sure to insert a line break at the end of the output.


Input Example 1

1234 2

Output Examle 1

12

In this case Dave can only use up to 2 kinds of numbers.

He will input the closest integer 1222, so the difference is 12.


Input Example 2

800000 1

Output Example 2

22223

Dave can use only 1 number, so 777777 is the closest integer.


Inout Example 3

7328495 10

Output Example 3

0

In this case Dave's calculator is not broken at all.

He can input the given integer A as is.


Input Example 4

262004 2

Output Example 4

218

The closest integer is 262222.

解题思路:

设A的数字长度为L,首先寻找K个数,对剩余的L-K数分别计算最大值和最小值,在计算的时候要考虑借位和进位的情况。

具体算法(java版,直接AC)

  1 import java.math.BigInteger;
  2 import java.util.Arrays;
  3 import java.util.Scanner;
  4 
  5 public class Main{
  6     
  7     public int[]available;
  8     public String target;
  9     public int limited;
 10     
 11     public Main(String target,int limited){
 12         this.available=new int[10];
 13         this.target=target;
 14         this.limited=limited;
 15     }
 16     private int getIntByIndex(int index){
 17         return this.target.charAt(index)-'0';
 18     }
 19     
 20     private BigInteger substract(String str1,String str2){
 21         BigInteger a=new BigInteger(str1);
 22         BigInteger b=new BigInteger(str2);
 23         if(a.compareTo(b)>0){
 24             return a.subtract(b);
 25         }else{
 26             return b.subtract(a);
 27         }
 28     }
 29     private String convertTo(int[]array){
 30         StringBuffer buffer=new StringBuffer();
 31         for(int i=0;i<array.length;i++){
 32             buffer.append(array[i]);
 33         }
 34         return buffer.toString();
 35     }
 36     
 37     public void solve(){
 38         int index=0;
 39         int k=this.limited;
 40         for(;index<this.target.length();index++){            
 41             int j=this.getIntByIndex(index);
 42             if(this.available[j]==0){
 43                 if(k==0){
 44                     break;
 45                 }
 46                 this.available[j]=1;
 47                 k--;
 48             }            
 49         }
 50         if(index==this.target.length()){
 51             System.out.println("0");
 52             return;
 53         }
 54         int[]copy=Arrays.copyOf(this.available, this.available.length);
 55         BigInteger diff1=this.substract(this.convertTo(this.calculateMax(copy, index)), this.target);
 56         BigInteger diff2=this.substract(this.target,this.convertTo(this.calculateMin(this.available, index)));
 57         if(diff1.compareTo(diff2)>0){
 58             System.out.println(diff2.toString());
 59         }else{
 60             System.out.println(diff1.toString());
 61         }
 62     }
 63     
 64     private int getValue(int[] avail,boolean less){
 65         if(less){
 66             for(int i=0;i<=9;i++){
 67                 if(avail[i]>0)
 68                     return i;
 69             }
 70         }else{
 71             for(int i=9;i>=0;i--){
 72                 if(avail[i]>0)
 73                     return i;
 74             }
 75         }
 76         return -1;
 77     }
 78     
 79     public int[] calculateMax(int[] avail,int index){
 80         int[]result=new int[this.target.length()];
 81         int nextValue=Integer.MIN_VALUE;
 82         for(int i=0;i<index;i++){
 83             result[i]=this.getIntByIndex(i);
 84         }
 85         for(int i=0;i<=9;i++){
 86             if(avail[i]>0&&i>this.getIntByIndex(index)){
 87                 nextValue=i;
 88                 break;
 89             }
 90         }
 91         if(nextValue==Integer.MIN_VALUE){
 92             nextValue=this.getIntByIndex(index-1)+1;
 93             for(int j=index-1;j>=0;j--){
 94                 if(result[j]==nextValue-1){
 95                     result[j]=nextValue;
 96                 }
 97             }
 98             result[index-1]=nextValue;
 99             avail[nextValue-1]=0;
100             int min=Integer.MAX_VALUE;
101             if(avail[nextValue]==0){
102                 avail[nextValue]=1;
103                 min=this.getValue(avail, true);
104             }
105             for(int j=index;j<this.target.length();j++){
106                 result[j]=min;
107             }
108         }else{
109             result[index] = nextValue;
110             int min=this.getValue(avail, true);
111             for(int i = index + 1; i < result.length; i++)
112             {
113                 result[i] = min;
114             }
115         }
116         return result;
117     }
118     
119     public int[] calculateMin(int[] avail,int index){
120         int[]result=new int[this.target.length()];
121         int nextValue=Integer.MIN_VALUE;
122         for(int i=0;i<index;i++){
123             result[i]=this.getIntByIndex(i);
124         }
125         for(int i=9;i>=0;i--){
126             if(avail[i]>0&&i<this.getIntByIndex(index)){
127                 nextValue=i;
128                 break;
129             }
130         }
131         if(nextValue==Integer.MIN_VALUE){
132             if(index==1&&this.getIntByIndex(0)==1){
133                 result=new int[this.target.length()-1];
134                 for(int j=0;j<result.length;j++){
135                     result[j]=9;
136                 }
137             }else{
138                 nextValue=this.getIntByIndex(index-1)-1;
139                 for(int j=index-1;j>=0;j--){
140                     if(result[j]==nextValue+1){
141                         result[j]=nextValue;
142                     }
143                 }
144                 result[index-1]=nextValue;
145                 avail[nextValue+1]=0;
146                 int max=Integer.MIN_VALUE;
147                 if(avail[nextValue]==0){
148                     avail[nextValue]=1;
149                     max=this.getValue(avail, false);
150                 }
151                 for(int j=index;j<this.target.length();j++){
152                     result[j]=max;
153                 }
154             }
155         }else{
156             result[index] = nextValue;
157             int max=this.getValue(avail, false);
158             for(int i = index + 1; i < result.length; i++)
159             {
160                 result[i] = max;
161             }
162         }
163         return result;
164     }
165     
166     public static void main(String[] args) {
167         Scanner scanner=new Scanner(System.in);
168         Main m=new Main(scanner.next(),scanner.nextInt());
169         m.solve();
170     }
171 }
原文地址:https://www.cnblogs.com/pinxiong/p/4071928.html