简单游戏(easygame)

简单游戏(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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43346722/article/details/108148776