C++ 信息学奥赛,要求青少年具备一定的阅读理解能力、抽象逻辑能力。
问题描述
最近正在上映电影“魔境仙踪”,爱魔幻故事的卡卡西特别想去看,于是央求着妈妈带她去影院。卡卡西的妈妈对她微微一笑,说:“那好吧,卡卡西,让我来考考你,如果你能解决我出的难题,就可以带你去影院哦!你想要试试吗?”“当然啦,尽管出题吧……”,卡卡西信心满满,于是妈妈开始出题。
题目是这样的:现连续写下从整数 1 开始到某个整数 N(十进制)之间的所有整数时,能得到如下的数字序列:12345678910111213141516171819202122…,当 N 为 20 时,得到的数字序列为:1234567891011121314151617181920。
请编写一个程序,计算这个序列中的数字字符的个数。同学们,你们能帮助卡卡西解决这个问题码?
输入格式
一行,一个正整数N(1≤N≤10000)。
输出格式
一个正整数,表示由给定的整数所产生的序列的数字个数。
输入输出样例
输入样例 | 输出样例 |
---|---|
15 | 21 |
20 | 31 |
样例解释:当 N=15 时,得到的数字序列为:123456789101112131415,这个数字序列包含的数字字符个数为 21 个。
PS:书写代码前,需充分理解题目。
题解 1
思路分析:使用 if...else if...else if
,按照 N 不同位数,分别计算结果的字符个数,并返回。
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
// 1≤N≤10000
int ans = 0;
if(n <= 9) {
ans = n;
} else if(n <= 99) {
ans = (n - 9) * 2 + 9;
} else if(n <= 999) {
ans = (n - 99) * 3 + 90 * 2 + 9;
} else if(n <= 9999) {
ans = (n - 999) * 4 + 900 * 3 + 90 * 2 + 9;
} else if(n == 10000) {
ans = 5 + 9000 * 4 + 900 * 3 + 90 * 2 + 9;
}
cout << ans << endl;
return 0;
}
题解 2
思路分析:将 题解 1 中,if
语句优化抽取为公式 ans = cnt * n - (pow(10, cnt) - 10) / 9 + (cnt - 1);
(cnt
为整数 N 的位数),将此类问题泛化。
PS:公式的抽取中,隐含了等比数列的求和公式,需了解该部分知识点。
#include <iostream>
#include <cmath>
using namespace std;
int main(){
int n;
cin >> n;
int ans = 0, cnt = 0;
int m = n;
while(m) {
cnt ++;
m /= 10;
}
ans = cnt * n - (pow(10, cnt) - 10) / 9 + (cnt - 1);
cout << ans << endl;
return 0;
}