题目链接:http://soj.sysu.edu.cn/1240
题目大意:假设有一个表盘出现了故障,里面不会出现数字4,即 3 的下一位是5,如:399下一位是500。现在给出一个坏表盘上的数字(即不会出现 4 ),要求求出实际数字的大小,即如果表盘正常工作从1开始依次加一后应该出现的数字。
解题思路:先算出应该减去的总和,然后再用原来的数相减即可。那么,应该如何算出要减去的总和呢?假设有一个n位数a1a2a3...an,我们可以先算a100....0(除了最高位a1,其他位都是0)应该减去多少,然后再算a200..0(除了次高位a2,其他位都是0)应该减去多少,以此类推,最后把这些应该减去的总和加起来就得到了总的应该减去的数。现在问题的关键就在于解决满十、满百、满千...应该减去的数。这里可以用递推来实现,我们可以很清楚地看到,满10我们应该减一,满100我们应该减19(即1*9+10),满1000我们应该减271(即19*9+100)...每下一个数都 等于 上一个数*9+10^k(k = 1,2,3...)
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
/* 变量说明
a[]数组用于存储满一、满十、满百...应该减去的数
num[]数组用于存储读入数的各个位上的数,低位数字存在在数组低位中
sum 用于记录应该减去的总和
count 用于表示num数组的长度
*/
int a[10], sum, num[10], n, count, temp;
a[0] = 0;
// 利用递推算出满十、满百、满千...应该减去的数
for (int i = 1; i < 9; i++)
a[i] = a[i - 1] * 9 + pow(10, i - 1);
while (1)
{
cin >> n;
if (n == 0)
break;
count = 0;
temp = n;
// 将读入的数的各个位上的数字存储在数组中,低位数字放在数组低位
while (temp)
{
num[count++] = temp % 10;
temp /= 10;
}
sum = 0;
// 计算应该减去的总和
for (int i = count - 1; i >= 0; i--)
{
if (num[i] > 4)
sum += (num[i] - 1) * a[i] + pow(10, i);
else
sum += num[i] * a[i];
}
cout << n << ": " << n - sum << endl;
}
return 0;
}