简单游戏(easygame) \operatorname{简单游戏(easygame)} 简单游戏(easygame)
题目链接: SSL比赛 1507 \operatorname{SSL比赛\ 1507} SSL比赛 1507
题目
一天,小 R 准备找小 h 去游泳,当他找到小 h 时,发现小 h 正在痛苦地写着一列数, 1 1 1 , 2 2 2 , 3 3 3 , … … … , n n n ,于是就问小 h 痛苦的原因,小 h 告诉他,现在他要算 1.. n 1..n 1..n 这些数里面, 1 1 1 出现的次数是多少,如 n = 11 n=11 n=11 的时候,有 1 , 10 , 11 1,10,11 1,10,11 共出现 4 4 4 次 1 1 1 ,现在给出 n , n, n, 你能快速给出答案么?
输入
一行,一个整数 n n n
输出
一个整数,表示 1.. n 1..n 1..n 中 1 1 1 出现的次数。
样例输入
11
样例输出
4
数据范围
对于 30 % 30\% 30% 的数据: n < = 1000 ; n<=1000; n<=1000;
对于 100 % 100\% 100% 的数据: n < = m a x l o n g i n t ; n<=maxlongint; n<=maxlongint;
思路
这道题是一道数学题,要分类讨论。
我们一位一位的求:
对于个位,每十个这里就出现了 1 1 1 个 1 1 1 ;对于十位,每百个这里就出现了 10 10 10 个 1 1 1 ;对于百位,没千个就出现了 100 100 100 个 1 1 1 。
那它前面组成的数字就是有多少个每一个,或者十个,百个,等等。
(想 233 233 233 ,对于十位,就有 2 2 2 个 10 10 10 )
接着就来看它这一位,可以发现,如果这一位是 0 0 0 ,就正常。如果这一位大于 1 1 1 ,就会多一个每一个,或者十个,百个,等等。
但是如果这一位等于 1 1 1 呢?
那我们发现,它后面组成的数字就是多了多少次 + 1 +1 +1 。
为什么要加一呢?就是因为比如 10 10 10 ,在看到十位的时候,虽然后面组成的数字是 0 0 0 ,但是可以看出十位出现了 1 1 1 次 1 1 1 。因为 10 10 10 里面十位是有一个 1 1 1 的。
代码
#include<cstdio>
#define ll long long
using namespace std;
ll n, ans;
ll more, times, sheng;
int main() {
scanf("%lld", &n);//读入
for (ll wei = 1; wei <= n; wei *= 10) {
//枚举每一位
more = n % (wei * 10) / wei;//这一位
times = n / (wei * 10);//它前面组成的数字
sheng = n % wei;//它后面组成的数字
if (more > 1) ans += times * wei + wei;
else if (more == 1) ans += times * wei + sheng + 1;//分类讨论
else ans += times * wei;
}
printf("%lld", ans);//输出
return 0;
}