我目前正在参加Google Kickstart比赛的练习,目前正在Even Digits problem from Round A of 2018上工作。
我创建了以下算法,当我对其进行测试时,它的效果很好。但是问题是,当我将其提交到平台并按下“尝试”按钮时,它表明我的输出不正确。
我尝试使用更大或更复杂的数字对其进行测试,但我只是找不到情况。
问题描述:
Supervin有一个独特的计算器。该计算器只有一个显示屏,一个加号按钮和一个减号按钮。当前,整数 N 显示在计算器显示屏上。
按加号按钮会将计算器显示屏上显示的当前数字增加1。类似地,按减号按钮会将计算器显示屏上显示的当前数字减少1。计算器不显示任何前导零。例如,如果 100 显示在计算器显示屏上,则按下减号按钮一次将使计算器显示 99 。
Supervin不喜欢奇数,因为他认为奇数是“奇数”。因此,他只想使用计算器按钮来显示一个仅用偶数位表示的整数。由于计算器有点旧并且按钮难以按下,因此他希望使用最少的按钮按下次数。
请帮助Supervin确定按下按钮的最小次数,以使计算器显示没有奇数的整数。
输入
输入的第一行给出测试用例的数量, T 。接下来是 T 测试用例。 每行以包含整数 N 的一行开头: Supervin计算器上最初显示的整数。
这是我的代码:
public static void Main(string[] args)
{
var SCount = Console.ReadLine();
long Count = Convert.ToInt64(SCount);
for (long i = 0; i < Count; i++)
{
var val = Console.ReadLine();
long l = Convert.ToInt64(val);
Console.WriteLine("Case #{0}: {1}", i + 1, Slover4(l));
}
}
public static long Slover4(double N)
{
char[] odds = { '1', '3', '5', '7', '9' };
double presses_p = 0;
double PN = N;
double presses_n = 0;
double NN = N;
double pdegits = -1;
for (int i = PN.ToString().Length - 1; i >= 0; i--)
{
pdegits += 1;
//2110
//2018 EVEN EVEN (ODD EVEN) ---->
//11 ODD OOD <----
//1 ODD ---->
//42 EVEN EVEN XXXXX 6969 1 | 6970 30 | 7000 -200 | 6800
#region Positives
if (i > 0 && odds.Contains(PN.ToString()[i]) &&
odds.Contains(PN.ToString()[i - 1])) // ODD - ODD
{
var val = int.Parse(string.Concat(PN.ToString()[i - 1], PN.ToString()[i]));
var lv = int.Parse(PN.ToString()[i].ToString());
//15 17 19
//5 3 1
presses_p += (5 - (lv - 5)) * Math.Pow(10, pdegits);
PN += (5 - (lv - 5)) * Math.Pow(10, pdegits);
}
else if (i != 0 &&
!odds.Contains(PN.ToString()[i - 1]) &&
odds.Contains(PN.ToString()[i])) // EVEN - ODD
{
presses_p += Math.Pow(10, pdegits);
PN += Math.Pow(10, pdegits);
}
else if (i != 0 &&
odds.Contains(PN.ToString()[i - 1])) // ODD - EVEN
{
var val = int.Parse(string.Concat(PN.ToString()[i - 1], PN.ToString()[i]));
var lv = int.Parse(PN.ToString()[i].ToString());
//10 12 14 16 18
//10 8 6 4 2 ->
//10 12 14|
//2 4 6 |
presses_p += (10 - lv) * Math.Pow(10, pdegits);
PN += (10 - lv) * Math.Pow(10, pdegits);
}
else if (i == 0 &&
odds.Contains(PN.ToString()[i])) // ODD Only
{
presses_p += Math.Pow(10, pdegits);
PN += Math.Pow(10, pdegits);
}
#endregion
#region Negatives
if (i > 0 &&
odds.Contains(NN.ToString()[i]) &&
odds.Contains(NN.ToString()[i - 1])) // ODD - ODD
{
var val = int.Parse(string.Concat(NN.ToString()[i - 1], NN.ToString()[i]));
var lv = int.Parse(NN.ToString()[i].ToString());
//11 13 15 17 19
//3 5 7 9 11
presses_n += (3 + (lv - 1)) * Math.Pow(10, pdegits);
NN -= (3 + (lv - 1)) * Math.Pow(10, pdegits);
}
else if (i != 0 &&
!odds.Contains(NN.ToString()[i - 1]) &&
odds.Contains(NN.ToString()[i])) // EVEN - ODD
{
presses_n += Math.Pow(10, pdegits);
NN -= Math.Pow(10, pdegits);
}
else if (i != 0 &&
odds.Contains(NN.ToString()[i - 1])) // ODD - EVEN
{
var val = int.Parse(string.Concat(NN.ToString()[i - 1], NN.ToString()[i]));
var lv = int.Parse(NN.ToString()[i].ToString());
//10 12 14 16 18
//2 4 6 8 10 <-
presses_n += (2 + lv) * Math.Pow(10, pdegits);
NN -= (2 + lv) * Math.Pow(10, pdegits);
}
else if (i == 0 &&
odds.Contains(NN.ToString()[i])) // ODD Only
{
presses_n += Math.Pow(10, pdegits);
NN -= Math.Pow(10, pdegits);
}
#endregion
}
//$"P:{presses_p} - N - {presses_n}";
return presses_p < presses_n ? (long)presses_p : (long)presses_n;
}
答案 0 :(得分:4)
好吧,让我们从退化的案例开始:
2048
),我们将返回0
64087
),我们返回1
现在让left
是最左边的奇数(leftDigit
)的索引,例如
2480032581
^
left = 5 (since 2, 4, 8, 0, 0 are even)
leftDigit = 3
我们可以将初始号码转换为任意数字(通过按-按钮)
2480028888
或(按 + 按钮)进入
2480040000
最后,我们可以比较这两种可能性,并采用需要更少印刷机的一种方法:
"-" wants 2480032581 - 2480028888 == 3693 presses
"+" wants 2480040000 - 2480032581 == 7419 presses
对于给定的数字,按-
是更好的策略,因此我们返回3693
。
请注意,如果leftDigit
为9
,我们将坚持按"-"
进行操作(并忽略+
策略)。
C#代码:
private static long Solution(string value) {
int left = -1;
for (int i = 0; i < value.Length; ++i) {
if ((value[i] - '0') % 2 != 0) {
left = i;
break;
}
}
if (left < 0)
return 0; // All even digits number
else if (left == value.Length - 1)
return 1; // The very last digit is the only odd one
long initial = long.Parse(value.Substring(left));
int leftDigit = value[left] - '0';
if (leftDigit == 9)
return initial - long.Parse(new string('8', value.Length - left));
long plus =
long.Parse((leftDigit + 1).ToString() + new string('0', value.Length - left - 1)) -
initial;
long minus = initial -
long.Parse((leftDigit - 1).ToString() + new string('8', value.Length - left - 1));
return plus < minus ? plus : minus;
}
演示:
string[] tests = new[] {
"42",
"11",
"1",
"2018"
};
string report = string.Join(Environment.NewLine, tests
.Select(test => $"{test,6} -> {Solution(test),3}"));
结果:
42 -> 0
11 -> 3
1 -> 1
2018 -> 2