首页 > 试题广场 >

Counting Ones (30)

[编程题]Counting Ones (30)
  • 热度指数:1543 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
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.

输入描述:
Each input file contains one test case which gives the positive N (<=230).


输出描述:
For each test case, print the number of 1's in one line.
示例1

输入

12

输出

5
推荐
题目描述:
首先,翻译一下这个题。
题目的意思是:给出一个正整数,应该返回0到该正整数之间的十进制形式的 1出现的个数。
解题思路:
(1)将0 1----n数字列出  为了方便这里假设n为121  也就是000-121
(2)首先看所有数字的个位 这里分为三种情况就是n的个位大于1 小于1  等于1。 
  n的个位为1  那么  1出现的次数为00“1”-12“1”  前面的数字是变化的从00-12 有13中情况;  n的个位大于1  那么 如122的情况 1出现的次数将是 00“1”-12“1” 也是13,但是如果讨论的是十位就不一样了,这是需要重点考虑的。
  n的个位小于1  那么  如120的情况 1出现的次数将是 00“1”-11“1”  出现的情况是11次。
 (3)对每个十进制位进行讨论,将结果相加。但是当n是十位 、百位(非个位的)的情况下,要相对复杂一点,上面的只是启发一下解题思路。

下面的是正式的解题方法:  假设数字为abcde,对于abcde中的每一个数字,可以根据该数字与1的关系,求在该数字对应位置上1出现的次数。
具体来说:
假设我们要求百位出现1的次数,此时我们可以根据c与1的关系,求出百位1出现的次数。
(1)如果c = 0,则1出现的次数等于ab * 100,即 c前面的数 * c对应的基数
在该情况下,百位出现1的次数只与c前面的数有关。
(2)如果c = 1,则1出现的次数等于(ab * 100) + (de + 1),即(c前面的数 * c对应的基数) +( c后面的数 + 1)
在该情况下,百位出现1的次数与c前面和c后面的数有关。
(3)如果c = 2,则1出现的次数等于(ab + 1)*100,即(c前面的数 +1)* c对应的基数
题目代码:
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
int NumberOf1Between1AndN(int n)
{
   	int result=0,sum=0,std=1,i=n;
	while(i/std){
		int temp=i/(std*10);
		int num_bit=(i%(std*10))/std;
		if(num_bit==0) sum=temp*std;
		else if(num_bit==1) sum=temp*std+i%std+1;
		else 
			sum=(temp+1)*std;
		result=result+sum;
		std=std*10;
		sum=0;
	}
	return result;
}
int main(){
        int num=0;
        scanf("%d",&num);
        num=NumberOf1Between1AndN(num);
        printf("%d\n",num);
    return 0;
}
复杂度分析:
从解题思路的分析中可以看出:
其复杂度为输入正整数的n的十进制位数,也就是如果输入的是2位数(10-99) 执行次数为2,为5位数则while的执行次数为5,所以这里这里复杂度为log10(n),即log以10为低b的对数。

编辑于 2015-08-18 22:07:05 回复(1)
1的总个数为1在1~n所有数中
个位数上有1的个数+十位数上有1的个数+...+亿位数上有1的个数+...
自己动手亲自找一遍规律就能得出答案:
首先,找规律:
13
个位数为1:1 11
十位数为1:10 11 12 13
1的总个数为: 2+4=6

23
个位数为1:1  11 21
十位数为1:10 11 12 13 14 15 16 17 18 19
1的总个数为:3+10=13

345
个位数为1:1 11 21 31 41 51 61 71 81 91 101 111 121 131 141   ...341
十位数为1:10 11 12 13 14 15 16 17 18 19  ...311 312 ...319
百位数为1:100  101...199
1的总个数为:100+40+35=175

进而可得通项:
通项:求某一位的1的个数
高n位*本位(比如百位就乘100)+  0                             (本位小于1)
1*本位                     (本位大于1)
低n位+1                  (本位等于1)
也就是说,某位(各位,十位...)1的总个数可能与其高位,低位以及自己的
值有关,具体对应情况如上

例如算12345:
个位1:1234*1+1(个位>=1加1)
十位1:123*10+10
百位1:12*100+100
千位1:1*1000+1000
万位1:2345+1
1的总个数为:8121

例如算23012:
个位1:2301*1+1
十位1:230*10+2+1  (十位=1加低位即2然后加1)
百位1:23*100            (百位为0加0)
千位1:2*1000+1000
万位1:10000
1的总个数为:19905

通俗来说,某位(个位,十位..)上1的个数=
基础数+当前位为>0,<0,=0时的情况,
而基础数为当前位前面的高位*当前位
例如:23012,当 当前位为百位时,基础数=23(前高位)*100+上面讨论的情况)


代码:
#include <iostream>
using namespace std;

int main()
{
int n,k=1,sum=0,curr,large,small=0;
cin>>n;
while(n>0)
{
curr=n%10;
large=n/10;
if(curr>1)
sum=sum+large*k+k;
else if(curr<1)
sum=sum+large*k;
else
sum=sum+large*k+small+1;
small=small+curr*k;     //记录一下低位,当 当前为为0时用
n=n/10;
k=k*10;
}
cout<<sum;
return 0;
}

编辑于 2017-08-28 23:16:44 回复(1)
#include <iostream>
using namespace std;
int main(){
    int n,a=1,ans=0;
    int left,now,right;
    cin>>n;
    while(n/a){
        left=n/a/10;  //当前位的高位数
        now=n/a%10;
        right=n%a;    //当前位的低位数
        if(now==0) ans+=left*a;                //高位为0到left-1,当前位为1时,每个带a个1
        else if(now==1) ans+=left*a+(right+1); //当前位为1时,还要加上高位为left时低位数个1
        else ans+=(left+1)*a;                  //当前位大于1时,高位0到left当前位为1,每个带a个1
        a*=10;
    }
    cout<<ans;
    return 0;
}

发表于 2018-02-15 20:51:07 回复(0)
n=int(input())
res,t=0,1
while n//t:
    l,p,r=n//(t*10),n//t%10,n%t
    res+=l*t
    res+=t if p>1 else r+1 if p==1 else 0
    t*=10
print(res) 
编辑于 2018-09-04 09:40:50 回复(0)
#include <iostream>

using namespace std;

int main()
{     int n,w=1,result=0;     int x,y,z;     cin>>n;     while(n/w)     {         x = n/w/10;         y = n/w%10;         z = n%w;         if(y==0)             result += x*w;         else if(y==1)             result += x*w+z+1;         else             result += (x+1)*w;         w *= 10;     }     cout<<result<<endl;     return 0;
}

发表于 2018-03-17 01:19:22 回复(0)
比较通用的数位DP的方式
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

typedef pair<int, int> P;
typedef long long ll;

const int N = 15;

int n;
int dp[N][10];  // dp[i][j]表示长度为i,以j开头,所有这种类型的数字,1的个数的和

ll solve(int n) {
  ll res = 0;
  vector<int> numbers;
  while (n) {
    numbers.push_back(n % 10);
    n /= 10;
  }
  reverse(numbers.begin(), numbers.end());
  int last = -1;
  for (int i = 0; i < numbers.size(); i++) {
    int cur = numbers[i];
    for (int j = 0; j < cur; j++) {
      res += dp[numbers.size() - i][j];
    }
    if (last == 1) {
      int t = 0;
      for (int j = i; j < numbers.size(); j++) {
        t = t * 10 + numbers[j];
      }
      res += t + 1;
    }
    last = numbers[i];
  }
  if (last == 1) res++;
  return res;
}

void debug() {
  for (int i = 1; i <= 3; i++) {
    for (int j = 0; j <= 9; j++) {
      printf("dp[%d][%d] = %d\n", i, j, dp[i][j]);
    }
  }
}

int main() {
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  dp[1][1] = 1;
  for (int i = 2; i <= 10; i++) {
    for (int j = 0; j <= 9; j++) {
      for (int k = 0; k <= 9; k++) {
        dp[i][j] += dp[i - 1][k];
      }
      if (j == 1) dp[i][j] += pow(10, i - 1);
    }
  }
  // debug();
  cin >> n;
  cout << solve(n) << endl;
  return 0;
}


发表于 2022-08-30 22:36:52 回复(0)
有同学可能在PTA过不了那两个测试点,那是因为,虽然他写了N为正数,但PTA测试点TM有负数,比如-1的1个数:为1
发表于 2022-11-25 15:58:08 回复(0)
#include<bits/stdc++.h>
using namespace std;

int main() {
	int n,a=1,answer=0,left,now,right;
	cin>>n;
	while(n/a!=0) {
		left=n/(a*10);
		now=n/a%10;
		right=n%a;
		if(now==0) {
			answer+=left*a;
		} else if(now==1) {
			answer+=left*a+right+1;
		} else {
			answer+=(left+1)*a;
		}
		a*=10;
	}
	cout<<answer<<endl;
	return 0;
}

发表于 2022-11-14 18:35:49 回复(1)
#include<iostream>
using namespace std;
int js(int n);
int num(int n,int m);
int main()
{
	int n,ans=0;
	cin >> n;
	int m = js(n);
	for (int i = 1; i <= m; i++) {
		ans += num(n, i);
	}
	cout << ans << endl;
	return 0;
}
int js(int n)
{
	int m = 0;
	if (n % 10 == 0) n++;
	while (n!=0)
	{
		m++;
		n /= 10;
	}
	return m;
}
int num(int n, int m)
{
	int m1 = (int)(pow(10.0, m));
	int m2 = (int)(pow(10.0, m-1));
	int m3 = (n % m1 + 1) - m2;
	if (m3 > m2)m3 = m2;
	if (m3 < 0)m3 = 0;
	return (n / m1)*m2 + m3;
}
找规律直接计算出来
发表于 2021-11-18 21:13:21 回复(0)
ok
#include<cstdio>
int n,Pow[21],ans=0,dp[21];
int dfs(int n){
	int cnt=0;
	while(n){
		cnt++;
		n/=10;
	}
	return cnt;
}
int main(){
	scanf("%d", &n);
	Pow[1]=1;
	for(int i=1;i<=19;i++){//当有位9时,1的总个数
		dp[i]=Pow[i]+dp[i-1]*10;
		Pow[i+1]=Pow[i]*10;//每次都要加翻10倍的1
	}
	while(n){
		int cnt=dfs(n),a;
		a=n/Pow[cnt];
		if(cnt>1)
			a==1 ? ans+=dp[cnt-1]+(n%Pow[cnt]+1) : ans+=a*dp[cnt-1]+Pow[cnt];//a>1时 要加满10的cnt次方个1
		else ans++;
		n=n%Pow[cnt];
	}
	printf("%d",ans);
	return 0;
}

发表于 2021-02-08 12:06:13 回复(0)
感觉还没这样的思路,我是用的递归,对每个位置进行递归
#include <bits/stdc++.h>
using namespace std;
string str;
int df2(int pos,int sum1)
{

    if(pos==str.size()-1)
    {
        int posNumber=str[pos]-'0';

        long sum=0;
        for(int i=0; i<=9; i++)
        {
            if(i==1)
                sum+=sum1+1;
            else
                sum+=sum1;
        }
        return sum;
    }

    int posNumber=str[pos]-'0';
    long sum=0;
    sum+=df2(pos+1,sum1+1);
    sum+=df2(pos+1,sum1)*9;

    return sum;

}

int df(int pos,int sum1)
{

    if(pos==str.size()-1)
    {
        int posNumber=str[pos]-'0';

        long sum=0;
        for(int i=0; i<=posNumber; i++)
        {
            if(i==1)
                sum+=sum1+1;
            else
                sum+=sum1;
        }
        return sum;
    }

    int posNumber=str[pos]-'0';
    long sum=0;
    for(int i=0; i<=posNumber; i++)
    {
        if(i==posNumber)
        {
            if(i==1)
                sum+=df(pos+1,sum1+1);
            else
                sum+=df(pos+1,sum1);
        }

        else
        {
            if(i==1)
                sum+=df2(pos+1,sum1+1);
            else
                sum+=df2(pos+1,sum1);
        }

    }
    return sum;

}


int main(void)
{
    long N=99;
    cin>>N;
    str=to_string(N);

    cout<<df(0,0);

}



发表于 2020-06-05 23:42:55 回复(0)
算法:将数拆分为两部分,如10010拆分为10000-1=9999 和 10,分别计算count(9999)和count(10),再根据条件得到计算公式即可。本算法最慢耗时4ms。
#include<iostream>
(720)#include<math.h>

using namespace std;

int count1 = 0;

pair<int, int> gethi(int n) 
{
	int c = 1;
	while (n >= 10) {
		n /= 10;
		c = 10 * c;
	}
	return pair<int, int>(n, c);
}

int count(int n)
{
	if (n <= 0) return 0;
	if (n <= 11) return n / 10 + 1 + 2 * (n / 11);
	else if (n > 11 && n < 20) return count(11) + n - 11;
	else if (n >= 20 && n < 100) return count(19) + (n - 1) / 10 - 1;
	else {
		pair<int, int> res = gethi(n);
		int left = res.first;
		int sub = res.second;
		int right = n - left * sub;
		int leftc, rightc;
		if (right == 0 && left == 1) return 1 + count(sub - 1);
		if (right == 0 && left >= 1) return sub + left * count(sub - 1);
		if (left == 0) return count(right);
		else if(left == 1){
			leftc = right + 1 + count(sub - 1);
			rightc = count(right);
			return leftc + rightc;
		}
		else {
			leftc = left * count(sub - 1) + sub;
			rightc = count(right);
			return leftc + rightc;
		}
	}
}
int main()
{
	int n = 0;
	cin >> n;
	cout << count(n);
	return 0;
}



发表于 2020-03-27 14:17:43 回复(0)

//不会做,模仿大神们的。。。。
//分别找每一位上1的个数
//
//高n位*本位(比如百位就乘100)               (本位小于1) 
//高n位*本位(比如百位就乘100)+低n位+1          (本位等于1)
//高n位*本位(比如百位就乘100)+1*本位            (本位大于1)     
/*
想一想,也很容易想到为什么要去与1判断大小。假设数为23012,那么要判断百位上为1的个数,
可以知道百位前面两位00-22有23种情况,所以是23*100(后面两位的值任意,就是100种),
但当前面两位为23时,这时候百上还有没有可能为1呢?在这个例子中,百位上为0(小于1),
因此不可能再出现1了,这时候就不加了。那么又比如说十位上为1,则是230*10+2+1,加一是为了保证个位为0也要算上。
注意:最高位前的高n位看作是0,最低位后的低n位也看做是0。
*/
/*
看到大神用数位dp,百度了半天才勉强看懂了代码,但是还不会写,先记下来学习一下吧,代码直接copy的
*/
/*
#include<iostream>
using namespace std;
int main() {
	int n;
	cin >> n;
	int count = 0;
	int tmp = 1;//开始为个位,tmp为数位(比如百位就为100)
	while (n / tmp) {
		int number = n;
		int low = number % tmp;
		int now = (n / tmp) % 10;//完美解决最高位最低位的边界问题!!!
		int high = (n / tmp) / 10;
		if (now < 1) {
			count += high * tmp;
		}
		else if (now == 1) {
			count += high * tmp + low + 1;//加一是为了算上0
		}
		else {
			count += high * tmp + tmp;
		}
		tmp *= 10;
	}
	//由于0算进去也不会影响1的值,因此这里不用管0。
	printf("%d", count);
}
*/

#include<iostream>
using namespace std; 
int num[12],dp[12][12]; //dp[i][j]表示每一个状态对应下“1”的数目
int dfs(int pos,int now,int limit){   //now表示当前位的前面的位中有几个1。      123
 if(pos==-1)return now;   
 int& ans=dp[pos][now];//引用类型,dp[i][j]表示当第i位前面有j个1的状态下有多少个“1”出现
 if(!limit&&ans!=-1)
  return ans;  
 ans=0;  
 int up=limit?num[pos]:9;   
 for(int i=0;i<=up;i++){   
  ans+=dfs(pos-1,i==1?now+1:now,limit&&i==up);  
 }  
 return ans; 
} 
int solve(int x){   
 int cnt=0;  
 while(x){   
  num[cnt++]=x%10;  
  x/=10;  
 }   
 return dfs(cnt-1,0,1);
} 
int main() {   
 int n;   
 scanf("%d",&n);
 memset(dp,-1,sizeof(dp)); 
 printf("%d\n",solve(n));
 return 0;
}



编辑于 2020-03-26 00:36:53 回复(0)

感谢第一位和第二位大佬写的思路,由此受到启发,发现此题是一个排列组合的数学题

#include<iostream>
#include<stdlib.h>
#include<math.h>
using namespace std;

int main() {
    int n = 0, left = 0, right = 0, cur = 0, k = 1, sum = 0, tem = 0, i = 0;
    cin >> n;
    while (n / k != 0) {
        tem = n / k;
        cur = tem % 10;//求出各部分的值
        left = tem / 10;
        right = n % (tem*(int)pow(10,i++));

        if (cur > 1) {
            sum = sum + (left+1) * k;
        }
        else if(cur < 1){
            sum = sum + left * k;
        }
        else {
            sum = sum + left * k + right + 1;
        }
        k *= 10;
    }
    cout << sum<<endl;
    system("pause");
    return 0;
}
发表于 2019-10-22 20:27:33 回复(0)
#include <iostream>
#include <algorithm>
#include <string>
#include <set>
#include <vector>
#include <map>
#include <cmath>
using namespace std;

//1049 Counting Ones
//我写的跟个**一样。。。看了别人的解析原来那么简单。

int get_length(int n) {
    int length = 0;
    while (n) { length += 1; n /= 10; }//判断几位数
    return length;
}

int main() {

    int n; //<=2^30 ,最高7位的样子
    cin >> n;

    int length = get_length(n);
    int summ = 0, num = n, res, cur,lower=0;
    //不断统计个位的1,十位的1,...
    //需要记录,[high,i+1],i,[i-1,0]
    for (int i = 1; i <= length; ++i) {
        res = num % 10;
        num = num / 10;
        cur = num * pow(10.0, i - 1);//320,则个位=32*1,百位3*10+
        //余数大于等于1则需要补当前位出现的壹
        if (res > 1) {
            cur += pow(10.0, i - 1);
        }
        else if (res == 1) {
            //看[i-1,0]
            cur += (lower+1);
        }

        summ += cur;

        lower += res * pow(10.0, i - 1);
    }
    cout << summ;
    return 0;
}


编辑于 2019-08-13 16:58:26 回复(0)
优雅解决 数位DP
#include <bits/stdc++.h>
using namespace std;
intnum[12],dp[12][12];
intdfs(intpos,intnow,intlimit){
    if(pos==-1)returnnow;
    int&ans=dp[pos][now];
    if(!limit&&ans!=-1)returnans;
    ans=0;
    intup=limit?num[pos]:9;
    for(inti=0;i<=up;i++){
        ans+=dfs(pos-1,i==1?now+1:now,limit&&i==up);
    }
    returnans;
}
intsolve(intx){
    intcnt=0;
    while(x){
        num[cnt++]=x%10;
        x/=10;
    }
    returndfs(cnt-1,0,1);
}
intmain()
{
    intn;
    scanf("%d",&n);
    memset(dp,-1,sizeof(dp));
    printf("%d\n",solve(n));
    return0;
}

发表于 2018-11-07 17:28:55 回复(0)
#include<bits/stdc++.h>
#define rep(i, a, b) for(int i=a;i<=b; ++i)
#define per(i, a, b) for(int i=a;i>=b;--i)
#define de(a) cout <<#a<<" => "<<a<<endl
#define dep(a) cout <<"(first, second) => "<<"("<<a.fi<<","<<a.se<<")"<<endl
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pob pop_back
#define ms(a, b) memset(a, b, sizeof(a))
#define pq priority_queue
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int>vi;
const int maxn = 1e2;
const int inf = 1e9+7;
ll n, m;
// ===============================
int main(){
//    freopen("in.txt", "r", stdin);
    scanf("%lld", &n);
    ll ans = 0;
    for(ll i=10; i<=n*10; i*=10) {
        int x = (n%i)/(i/10);
        if(x==0) ans+=(n/i)*(i/10);
        else if(x==1) ans+=(n/i)*(i/10)+(n%(i/10) + 1);
        else ans+=(n/i + 1) * (i/10);
    
    cout << ans <<endl;
    return 0; 
}

发表于 2018-07-29 22:16:50 回复(0)
#include <iostream>
#include <memory.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <string>
#include <map>
#include <set>
using namespace std;

vector<int> nums;

int get_one_n(string s)
{
if (s.size() == 1)
{
return s[0] == '0' ? 0 : 1;
}
int th = nums[s.size() - 1];
th *= (s[0] - '0');
if (s[0] > '1')
{
th += pow(10, s.size() - 1);
}
if(s[0] == '1')
{
th += atoi(s.substr(1, s.size()).c_str()) + 1;
}
th += get_one_n(s.substr(1, s.size()));
return th;
}

int main()
{
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
int N;
cin >> N;
char buf[100];
sprintf(buf,"%d", N);
string temp(buf);
int n = temp.size();
nums.resize(n + 1);
int total = 0;
nums[0] = 0;
for (int i = 1; i <= n; i++)
{
nums[i] = 10 * nums[i - 1] + pow(10,i-1);
}
cout << get_one_n(temp);
return 0;
}

发表于 2016-03-08 23:52:32 回复(0)
PAT官方系统这题每组数据时限只有惊人的10ms……
我数位dp太渣了,或者说,懒得思考……
于是,能怎么办呢?打表呗!
总体思路是每10~100W输出一个中间结果,然后线上每次运行只要算10~100W次即可。
每100W个打一个值出来,boom!表放得下,算的不够快,就22分。
这怎么行?
然后转换思路,改成打相邻两项的差,然后会发现,不同的差的数量很有限很有限(<20个),这样表的大小变得很小,于是可以每20W输出一项。
这样,代码大小16000B(最终11882B)和运行时限10ms(最慢4ms)都得到了满足,PAT官方网站上30分通过。
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <algorithm>
using namespace std;
typedef long long ll;

int table[]={};//表太大了,这里省略,大家可以自己打出来

int ones(int x){
	int ans=0;
	while(x){
		if(x%10==1)ans++;
		x/=10;
	}
	return ans;
}

int query(int id){
	if(id==-1) return 0;
	else if(id==0) return 100000;
	else if(id==1) return 100001;
	else if(id==2) return 200000;
	else if(id==3) return 299999;
	else if(id==4) return 300000;
	else if(id==5) return 300001;
	else if(id==6) return 400000;
	else if(id==7) return 499999;
	else if(id==8) return 500000;
	else if(id==9) return 500001;
	else if(id==10) return 600000;
	else if(id==11) return 699999;
	else if(id==12) return 700000;
	else if(id==13) return 800000;
	return 0;
}

int main(){
	table[0]=0;
	for(int i=1;i<sizeof(table)/sizeof(int);i++){
		table[i]=table[i-1]+query(table[i]);
	}
	int n;
	scanf("%d",&n);
	int ans=table[n/200000];
	for(int j=n/200000*200000+1;j<=n;j++)
		ans+=ones(j);
	printf("%d\n",ans);
    return 0;
} 


发表于 2016-01-29 22:46:40 回复(0)
啥头像
总体思路:
        逐位计算。对于某一位,如12345中的3,把数分成    12    3    45,则百位上的1的个数为13*100+45。
        注意的是某位分三种情况:0, 1, 大于1.三种情况计算方式略有不同,但可以用下面代码中的式子统一起来。

代码如下:
#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int n; scanf("%d", &n);
    int ones = 0;
    for(int m=1; m<=n; m*=10) {
        ones += (n/m + 8)/10 *m + (n/m%10 == 1)*(n%m+1);
    }
    printf("%d", ones);
    return 0;
} 


发表于 2015-12-13 09:59:44 回复(0)
yql头像 yql
//最笨的方法:遍历,求出每个数中1个数,累加...
public int NumberOf1Between1AndN_Solution(int n) {
        int sum=0;
        for(int i=1;i<=n;i++){
            sum+=numOfOne(i);
        }
        return sum;
    }

//数num中1的个数
    public  int  numOfOne(int num){
        int count=0;
         
        while(num!=0){
            if(num%10==1){
                count++;
            }
            num=num/10;
        }
        return count;
}

发表于 2015-08-18 21:23:33 回复(1)