题目描述:
"3"是一个很奇妙的数字,阿尔萨斯作为war3里的英雄,对“3”很感兴趣,他很想让"3"越多越好。 一天,阿尔萨斯发现手下站成了n个军团,第i个军团正好有i个人,于是他把所有军团的人数连续写成了一个长串(123456...),现在阿尔萨斯想知道,其中"3"出现了多少次,你能帮帮他吗?
输入:输入文件中仅包含一行一个整数n,含义如上所述,n<=10^13。
输出:输出文件中包含一行,代表“3”的个数。
样例输入: 99
样例输出:20
题目分析:本题的题目大意是求1到任意数n中 3的个数,例如1到4中有一个3,1到14中有两个3。要注意的是:33中含有两个3......看到n的条件(n值可以非常大)就可推测出本题一定和位数有关。那么我们就可以从每一位分析可以发现:从后向前来遍历每一位。
(1)、如果这位的数字小于3,就可以判断出这个位数上能出现的3的个数,就是这个数字前面的所有数字乘这个数的位数,比如:1221,个位出现三的个数就是122*1个,十位就是12*10个,百位就是1*100个所以3的个数就是 122+120+100=342个。
(2)、如果这位数字大于3.就要在(1)的(基础)上加(1*位数);如1421:个位出现三的个数就是142*1个,十位就是14*10(基础)个,百位就是1*100+1*10(这个数*位数) 所以3的个数为142+140+100+100=482个;
(3)如果这个数是3:就要在(1)的基础上加这个数后面的所有数字再加上自己本身的一个3;比如1231:个位数=123,十位数:12*10+1+1,百位数:1*100 总数就是123+120+1+1+100=345
思路就是这样,第一次写博客,难免有不周到的地方,欢迎大家的批评与指正。下面粘贴代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n;
long long x=0;
long long m=0;
while(cin>>n)
{
m=x=0;
long long ans=0;
m=n;
while(n!=0)
{
x++;
long long y=n%10;
long long a=1;
for(long long i=0;i<x-1;i++)
a=a*10;
if(y>3)
{
ans+=(long long )n/10*a+a;
}
else if(y==3)
{
ans+=(long long)n/10*a+m%a+1;
}
else
ans+=(long long )n/10*a;
n=(long long)n/10;
}
cout<<ans<<endl;
}
return 0;
}