Algorithm 面试难题:一个坏掉的计算器
时间限制:2秒/堆栈限制:256MB/内存限制:256MB 问题 戴夫的计算器坏了。当显示超过K个不同数字时,它将停止 Dave想输入一个整数A,但如果他输入的数字正确,计算器可能会停止。相反,他输入的是不会使计算器停止的最接近的整数 输出Dave输入与整数A之间的差值 输入 输入将以标准输入的以下格式给出Algorithm 面试难题:一个坏掉的计算器,algorithm,Algorithm,时间限制:2秒/堆栈限制:256MB/内存限制:256MB 问题 戴夫的计算器坏了。当显示超过K个不同数字时,它将停止 Dave想输入一个整数A,但如果他输入的数字正确,计算器可能会停止。相反,他输入的是不会使计算器停止的最接近的整数 输出Dave输入与整数A之间的差值 输入 输入将以标准输入的以下格式给出 A K 在第一行,您将得到整数A(1≦A.≦10^15),Dave要输入的整数,后跟空格和K(1)≦K≦10) ,他的计算器能识别的不同位数 输出 在一行中输出Dave输入与整数A之间
A K
- 在第一行,您将得到整数A(1≦A.≦10^15),Dave要输入的整数,后跟空格和K(1)≦K≦10) ,他的计算器能识别的不同位数
输入示例1
1234 2
12
输出示例1
1234 2
12
在这种情况下,Dave最多只能使用2个不同的数字。他将输入最接近的整数1222,因此差值为12
输入示例2
7328495 10
0
输出示例2
7328495 10
0
在这种情况下,戴夫的计算器一点也没有坏。他可以按原样输入给定的整数A
输入示例3
800000 1
22223
输出示例3
800000 1
22223
Dave只能使用一个数字,因此7777是最接近的整数
输入示例4
262004 2
218
输出示例4
262004 2
218
最接近的整数是262222
我已经用蛮力解决了这个问题 我尝试了所有可能的情况,我在1编辑N2 在每个步骤中,检查是否: a) 将关闭集的可能位数设置为小于当前位数,然后最大化剩余位数,这比当前答案更好 b) 将最接近的可能数字放在更大的位置,然后放在当前位置,然后最小化剩余数字,这比当前答案更好
然后,如果可能,将相同的数字放入下一个数字第一部分是:选择结果中使用的k位(10个可能的数字中的哪一个
通过一点数学(二项式系数),很容易计算出数字
给定k可能的不同数字组合。
最多可选择252种可能性(如果k=5,则为252种,否则不太多) 如果不清楚我在说什么:对于k=2,有
01,02,03,…09,12,13,…,19,23,24,…,89
不,例如11,因为它只有1,但k=2允许两个不同的数字。
没有,例如90,因为它与09、91=19等相同。
对于k=5,这些可能组合的计数为252,并且不会变大 查找当前k的所有(最多)252种可能性
在循环中迭代它们应该不会太难 对于每个可能性,请执行以下操作:
{ 在循环中,我们有A、K和当前选择的有效数字
对于解决方案(当然,后者在循环的每次迭代中都有所不同)
以A=12899,K=3,数字123为例。
现在搜索不允许的a的第一个数字(从左到右)。
在本例中,这将是12899,因为它的左1和左2是允许的 如果有下一个允许的较低数字(2),则将该数字(8)替换为下一个允许的较低数字(2)
并用可能的最高数字(3)替换其右边的所有内容。
12899=>12399=>12333
将结果12333保存在数组中的某个位置等。
如果没有下一个较低的可能数字,则不执行任何操作(不向数组发送任何内容) (带进位的适当加法将在更改后的数字左边引入一个新数字,
ie.无效。将找到具有此新数字的解决方案
当循环到达该数字时) 然后在另一个方向重复同样的事情:
用下一个更高的数字替换找到的数字
所有的东西都是最低的。这也在数组中,
当然,只有在有下一个更高的可能数字时。
在12899的情况下,8的唯一较高替代值是9,
但9是不可能的(只有123) } 整个循环完成后(每次迭代都产生
最多两个新数组项),您最多有502个可能的问题解决方案。
剩下要做的唯一一件事就是检查哪种溶液最好(即计算差值
在每个步骤中,您可以使用所需的数字、数字+1(mod 10)、数字-1(mod 10)或您以前使用过的任何数字。数字用完后,只能使用以前使用过的数字 这将创建一棵树。在每个步骤中,获取当前状态并计算下一级别中所有可能的新状态 您可以通过删除任何后续步骤来修剪树,这些步骤的增量与后续步骤中最小的增量之间的距离超过一定距离 这本质上是一个线性规划问题 下面是完整的算法!也许有人可以对修剪哪些树枝的决定进行微调,使之更快
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
public static class Converter
{
public static int ToInt(this IEnumerable<int> values)
{
return values.Aggregate(0, (total, v) => total * 10 + v);
}
public static IEnumerable<int> ToList (this int value)
{
if (value == 0) return Enumerable.Empty<int>();
else return value.ToString().Select(x => (int)x - '0').ToList();
}
}
class Program
{
static void Main(string[] args)
{
//int desired = 262004;
//int digits = 2;
int desired = 800000;
int digits = 1;
IEnumerable<State> currentStates = new[] { new State(0, 0, desired, digits) };
foreach (var digit in desired.ToList())
{
var nextStates = currentStates.SelectMany(x => x.NextPossibleStates());
foreach (var state in nextStates.OrderBy(s => s.Delta()).Take(10))
{
Console.WriteLine(state.ToString());
}
currentStates = nextStates;
Console.WriteLine("------------");
}
Console.ReadKey();
}
public class State
{
int index;
int current;
int desired;
int digitsRemaining;
private int desiredToNow()
{
return desired.ToList().Take(index).ToInt();
}
public int Delta()
{
return Math.Abs(desiredToNow() - current);
}
public State(int index, int current, int desired, int digitsRemaining)
{
this.index = index;
this.current = current;
this.desired = desired;
this.digitsRemaining = digitsRemaining;
}
private State Next (int nextDigit, int digitsRemaining)
{
return new State(this.index + 1, this.current * 10 + nextDigit, this.desired, digitsRemaining);
}
private IEnumerable<int> NextPossibleDigitsWithDuplicates()
{
if (this.digitsRemaining > 0)
{
int nextDesiredDigit = desired.ToList().Skip(index).First();
yield return nextDesiredDigit;
yield return (nextDesiredDigit + 9) % 10;
yield return (nextDesiredDigit + 1) % 10;
}
// Any previously used digit is OK
foreach (int i in this.current.ToList())
yield return i;
}
public IEnumerable<State> NextPossibleStates()
{
var possibles = this.NextPossibleDigitsWithDuplicates().Distinct();
var possiblesUsingExistingDigits = possibles.Where(p => this.current.ToList().Contains(p));
var possiblesUsingNewDigits = possibles.Where(p => !this.current.ToList().Contains(p));
var states = possiblesUsingExistingDigits.Select(p => Next(p, this.digitsRemaining))
.Concat(possiblesUsingNewDigits.Select(p => Next(p, this.digitsRemaining - 1)))
.ToList();
var bestDelta = states.Min(s => s.Delta());
// Now reject any that can never be better
// Guessing on the '2' here ...
var validStates = states.Where(s => s.Delta() < bestDelta + 2);
return validStates;
}
public override string ToString()
{
return this.current + " d=" + this.Delta() + " remaining " + this.digitsRemaining;
}
}
}
使用System.IO;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
公共静态类转换器
{
公共静态int-ToInt(此IEnumerable值)
{
返回值。聚合(0,(总计,v)=>总计*10+v);
}
公共静态IEnumerable ToList(此int值)
{
if(value==0)返回Enumerable.Empty();
else返回值.ToString().Select(x=>(int)x-'0').ToList();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
//期望的整数=262004;
//整数位数=2;
期望的整数=800000;
在里面