1049. Counting Ones (30)
The task is simple: given any positive integer N, you are supposed to count the total number of 1's in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1's in 1, 10, 11, and 12.
Input Specification:
Each input file contains one test case which gives the positive N (<=230).
Output Specification:
For each test case, print the number of 1's in one line.
Sample Input:12Sample Output:
5
顺便替浙大 pat 考试 搞个小宣传,大家可以去http://pat.zju.edu.cn/看看,有考试时候的一些习题,参加pat考试也会发个证书的,对锻炼自己编程能力算是不错的。这题主要是求1的个数,因为数据量比较大2的30次次方,暴力后面的肯定是超时。我们可以这么想,比如242这个数,我们可以这么想,可以分为200以下和200以上这两个段,我们只看200以下百位上的数字,从100-199这100个数,百位总共是100个1,然后百位下面的怎么想,我们可以想到从000-199这200个数字中,十位和个位中,每个数字出现的次数是相等的,所以我们可以用200*(1/10),就可以得到000-199这200个数所有的十位和个位上的1。接下来我们考虑200以上,也就是200-242这段数字,因为百位所有情况我们都已经考虑过,所以我们只需要考虑00-42这段数字,也就是可以划成对42求含有1的个数,这样可以一直前进。当然我们要注意一下142的不同之处,也就是开头是1的时候,这个时候没有从100-199的100个1,百位是从100-142 所以需要加上43个1。
还是太水咯,继续努力啊。。。
#include<iostream>
using namespace std;
long long dp[13];
long long find(long long n)
{
long long k, len, sum, num, num1, num2, p, i;
k = n;
len = 0;
while(k != 0)
{
len++;
k = k/10;
}
sum = 0;
for(i = len; i >= 1; --i)
{
num1 = n/dp[i-1];
num2 = n-dp[i-1]*num1;
if(num1 == 0)
{
continue;
}
else if(num1 == 1)
{
sum = sum+num2+1;
p = ((i-1)*dp[i-1])/10;
sum = sum+p;
n = n - num1*dp[i-1];
}
else
{
sum = sum+dp[i-1];
p = (i-1)*(num1*dp[i-1])/10;
sum = sum + p;
n = n - num1*dp[i-1];
}
}
return sum;
}
int main()
{
long long n, i, j;
dp[0] = 1;
for(i = 1; i <= 10; ++i)
{
dp[i] = dp[i-1]*10 ;
}
j = 1;
for(i = 1; i <= 30; ++i)
{
j = j*2;
}
while(cin>>n)
{
cout<<find(n)<<endl;
}
return 0;
}