题目来源: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)

 import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner; public class Main{ public int[]available;
public String target;
public int limited; public Main(String target,int limited){
this.available=new int[10];
this.target=target;
this.limited=limited;
}
private int getIntByIndex(int index){
return this.target.charAt(index)-'0';
} private BigInteger substract(String str1,String str2){
BigInteger a=new BigInteger(str1);
BigInteger b=new BigInteger(str2);
if(a.compareTo(b)>0){
return a.subtract(b);
}else{
return b.subtract(a);
}
}
private String convertTo(int[]array){
StringBuffer buffer=new StringBuffer();
for(int i=0;i<array.length;i++){
buffer.append(array[i]);
}
return buffer.toString();
} public void solve(){
int index=0;
int k=this.limited;
for(;index<this.target.length();index++){
int j=this.getIntByIndex(index);
if(this.available[j]==0){
if(k==0){
break;
}
this.available[j]=1;
k--;
}
}
if(index==this.target.length()){
System.out.println("0");
return;
}
int[]copy=Arrays.copyOf(this.available, this.available.length);
BigInteger diff1=this.substract(this.convertTo(this.calculateMax(copy, index)), this.target);
BigInteger diff2=this.substract(this.target,this.convertTo(this.calculateMin(this.available, index)));
if(diff1.compareTo(diff2)>0){
System.out.println(diff2.toString());
}else{
System.out.println(diff1.toString());
}
} private int getValue(int[] avail,boolean less){
if(less){
for(int i=0;i<=9;i++){
if(avail[i]>0)
return i;
}
}else{
for(int i=9;i>=0;i--){
if(avail[i]>0)
return i;
}
}
return -1;
} public int[] calculateMax(int[] avail,int index){
int[]result=new int[this.target.length()];
int nextValue=Integer.MIN_VALUE;
for(int i=0;i<index;i++){
result[i]=this.getIntByIndex(i);
}
for(int i=0;i<=9;i++){
if(avail[i]>0&&i>this.getIntByIndex(index)){
nextValue=i;
break;
}
}
if(nextValue==Integer.MIN_VALUE){
nextValue=this.getIntByIndex(index-1)+1;
for(int j=index-1;j>=0;j--){
if(result[j]==nextValue-1){
result[j]=nextValue;
}
}
result[index-1]=nextValue;
avail[nextValue-1]=0;
int min=Integer.MAX_VALUE;
if(avail[nextValue]==0){
avail[nextValue]=1;
min=this.getValue(avail, true);
}
for(int j=index;j<this.target.length();j++){
result[j]=min;
}
}else{
result[index] = nextValue;
int min=this.getValue(avail, true);
for(int i = index + 1; i < result.length; i++)
{
result[i] = min;
}
}
return result;
} public int[] calculateMin(int[] avail,int index){
int[]result=new int[this.target.length()];
int nextValue=Integer.MIN_VALUE;
for(int i=0;i<index;i++){
result[i]=this.getIntByIndex(i);
}
for(int i=9;i>=0;i--){
if(avail[i]>0&&i<this.getIntByIndex(index)){
nextValue=i;
break;
}
}
if(nextValue==Integer.MIN_VALUE){
if(index==1&&this.getIntByIndex(0)==1){
result=new int[this.target.length()-1];
for(int j=0;j<result.length;j++){
result[j]=9;
}
}else{
nextValue=this.getIntByIndex(index-1)-1;
for(int j=index-1;j>=0;j--){
if(result[j]==nextValue+1){
result[j]=nextValue;
}
}
result[index-1]=nextValue;
avail[nextValue+1]=0;
int max=Integer.MIN_VALUE;
if(avail[nextValue]==0){
avail[nextValue]=1;
max=this.getValue(avail, false);
}
for(int j=index;j<this.target.length();j++){
result[j]=max;
}
}
}else{
result[index] = nextValue;
int max=this.getValue(avail, false);
for(int i = index + 1; i < result.length; i++)
{
result[i] = max;
}
}
return result;
} public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
Main m=new Main(scanner.next(),scanner.nextInt());
m.solve();
}
}

A Broken Calculator 最详细的解题报告的更多相关文章

  1. hihoCoder 1114 小Hi小Ho的惊天大作战:扫雷·一 最详细的解题报告

    题目来源:小Hi小Ho的惊天大作战:扫雷·一 解题思路:因为只要确定了第一个是否有地雷就可以推算出后面是否有地雷(要么为0,要么为1,如果不是这两个值就说明这个方案行不通),如果两种可能中有一种成功, ...

  2. hihoCoder 1050 树中的最长路 最详细的解题报告

    题目来源:树中的最长路 解题思路:枚举每一个点作为转折点t,求出以t为根节点的子树中的‘最长路’以及与‘最长路’不重合的‘次长路’,用这两条路的长度之和去更新答案,最终的答案就是这棵树的最长路长度.只 ...

  3. hihoCoder 1052 基因工程 最详细的解题报告

    题目来源:基因工程 解题思路:假设基因序列长度为N,则需要计算基因序列前K个和后K个相同所需要的最少改变次数sum. 假设基因序列为 ATACGTCT (即M=8),K=6:interval=M-K= ...

  4. hihoCoder 1051 补提交卡 最详细的解题报告

    题目来源:补提交卡 解题思路:假设未提交程序的天数为:a1,a2,....,an,补交的张数为M.依次从a1,a2,....,an中去掉连续的 K 天(0<=K<=M),然后再来计算剩余数 ...

  5. hihoCoder 1049 后序遍历 最详细的解题报告

    题目来源:后序遍历 解题思路:开始时我只知道先通过先序.中序求出二叉树,然后再后序遍历二叉树,这当然也是一种解题思路,但是会做一些无用功,比如:计算二叉树.其实,可以直接通过先序序列和中序序列直接求出 ...

  6. hihoCoder 1041 国庆出游 最详细的解题报告

    题目来源:国庆出游 解题思路(下面是大神的写的): 把题目中的序列称作S,树称作T.那么对于S中的任意节点x,x的子孙节点如果在S出现的话,那么这个子孙节点的位置是有一定要求的:x的所有子孙节点在S中 ...

  7. A Great Alchemist 最详细的解题报告

    题目来源:A Great Alchemist A Great Alchemist Time limit : 2sec / Stack limit : 256MB / Memory limit : 25 ...

  8. A Mountaineer 最详细的解题报告

    题目来源:A Mountaineer (不知道该链接是否可以直接访问,所以将题目复制下来了) 题目如下: D - A Mountaineer Time limit : 2sec / Stack lim ...

  9. hihoCoder 1040 矩阵判断 最详细的解题报告

    题目来源:矩阵判断 解题思路: 1.判断矩阵的4个点是否相连,一共输入8个点,只要判断是否4个点是否都经过2遍: 2.判断矩阵中任意一条边与其他边之间要么平行,要么垂直.设A(x1,y1),B(x2, ...

随机推荐

  1. C++ 网教通直播刷屏反制 (思路启发)

    前言 那些手动刷屏的你们弱爆了! 直播间的讨论区是用来讨论的, 下次谁再在上课时间大量刷屏,就以暴制暴! 思路启发 #define VK_CTRL 0x11 //... keybd_event(VK_ ...

  2. mysql explain的extra

    导读 extra主要有是那种情况:Using index.Using filesort.Using temporary.Using where Using where无需多说,就是使用了where筛选 ...

  3. MAC地址表、ARP缓存表、路由表及交换机、路由器基本原理

    在网上找到了这篇讲述MAC地址,ARP协议和路由表的文章,如获至宝.一篇文章把组网中的相关概念讲的明明白白. 原文是发布在51cto博客上,但不知道为什么点进去却是404.让我没想到的是这个技术论坛上 ...

  4. vs.net/vscode中使用Beetlex创建vue应用

    平时在开发Vue应用则需要安装nodejs,vue cli等相关东西相对来说麻烦一些:如果你喜欢像vs.net/vscode创建普通项目一样就能开发Vue项目的话那可以尝试一下BeetleX针对Vue ...

  5. 如何在VMware虚拟机中安装CentOS6.7系统(下篇)

    上一篇文章讲到了CentOS6.7的安装教程,安装步骤到时区选择这块了,这篇文章接上篇文章,继续讲述CentOS6.7的安装教程,直至安装完成. 17.设置root的登录密码,日后登录虚拟机,用户名就 ...

  6. 4.WebPack-Loader

    一.什么是Loader WebPack默认只"认识"以*.js结尾的文件,如果想处理其他类型的文件,就必须添加Loader,有各种各样的Loader,每个Loader可处理不同类型 ...

  7. 安卓开发-Activity-多个Activity的开发方法。

    原文链接:https://blog.csdn.net/weixin_38420342/article/details/84344496 一.切换Activity的5种方式 Intent intent ...

  8. Kali中密码暴力破解工具hydra的使用

    前言 hydra是著名黑客组织thc的一款开源的暴力破解密码工具,功能非常强大,kali下是默认安装的,几乎支持所有协议的在线破解.密码能否破解,在于字典是否强大.本文仅从安全角度去讲解工具的使用,请 ...

  9. java soket通信总结 bio nio aio的区别和总结

    1 同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 自己上街买衣服,自己亲自干这件事,别的事干不了. 2 异步 异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作 ...

  10. vue cli3项目中使用qrcodejs2生成二维码

    组件的形式创建 1.下载依赖 npm install qrcodejs2 2.创建一个.vue的组件放置代码(我创建的是qrcodejs2.vue) //template中的代码 <templa ...