如何计算范围号1到n的0或1的总外观?

时间:2018-10-29 12:07:52

标签: c algorithm numbers

因此,我想查找数字范围内出现的0或1位数字。例如: 我想找到从数字1到100出现多少个0。答案是,0出现11次。我想将其实现为C,但是我不知道该怎么做。

所以,我想要做的第一件事是接收输入类型int(假设int为n)。然后,从数字1到n,在该范围内出现0个数字,在该范围内出现1个数字。然后打印总共出现0个和出现1个的总数。

这是我尝试过的,但尚未完成。

#include <stdio.h>

int main()
{
    int N, totalZero = 0;

    scanf("%d", &N);
    for (int i=N; i>0; i--)
    {
        //statement
    }
    return 0;
}

我不知道我必须在for内的//语句中做什么。

3 个答案:

答案 0 :(得分:1)

每次fields[event_id , skill_id] only once = i / 100的余数时,您都可以递增结果

1

答案 1 :(得分:0)

作为您的问题: 例如:1..100。 “零”数字将出现11次。也就是说:10 20 30 40 50 60 70 80 90和100(出现零数字的11倍)

那么for循环中的条件是什么?

#include <stdio.h>
#include <conio.h>

void count(int &n)
{
    printf("Input n: ");
    scanf("%d",&n);
    int value=0;
    int value2=0;
    for(int i=1;i<=n;i++)
    {
        int x = i;
        while (x>0)
        {
            if(x==100 && x%10==0)
            {
                x/=10;
                if(x==10)
                    value+=2;
            }
            else if(x%10==0)
                value++;
            else if(x%10==1) 
                value2++;
            x/=10;
        }
    }
    printf("\n%d",value);
    printf("\n%d",value2);
}

int main()

{
    int n;
    count(n);
    return 0;
}

答案 2 :(得分:0)

可以在数学上解决问题,而无需迭代范围内的每个数字并计算其位数。 通过计算特定数字在每个位置出现的次数来起作用。

示例

让我们以计算从13876的7位数为例。

每个位置出现7次的次数

  • 1位:(0)7, 17, 27, ..., 107,...3867 = 387 x 1
  • 10s位: (0)70, 71, 72, 73,..., 79, 170,..., 179,...3770, ..., 3779 = 38 x 10 = 380,介于3870,...,3876之间:7次,等于387
  • 100个位置:700, ... 799, ..., 3700, ... 3799 = (3 + 1) x 100 = 400
  • 1000处:0次。

总计= 387 + 387 + 400 = 1174

代码

我们将cntdigit(N, digit)定义为一个函数,该函数返回digit1N计数的次数。

long long cntdigit(long long n, int digit)
{
  long long j;
  long long res = 0;
  for(j = 1; n/j; j *= 10) {
    long long curdigit = (n / j) % 10;
    res += (n / j / 10) * j;
    if (curdigit > digit)
      res += j;
    else if (curdigit == digit)
      res += n % j + 1;

    if (digit == 0)
      res -= j;
  }
  return res;
}

时间复杂度:

可以解决时间复杂度为O(d)的任意数字,其中d10的基数n

说明:

  1. 对数字n的所有数字进行迭代,方法是将其除以10和mod 10的指数以得到每个数字。 (有关更多详细信息,请参见this。)
  2. 然后我们开始在每个地方计数digit发生的次数。
  3. 在每个地方,左边的部分(即被10的指数除以商的商)是一个数字出现在一个地方,十个地方,一百个地方等等的次数。
  4. 如果当前数字大于digit,则我们添加j(10s指数)以计算从0开始的所有商。
  5. 如果当前数字等于digit,则该数字在该位置出现的次数是指数+ 1的余数。
  6. 最后,如果要计数的数字为0,那么我们需要减去商为0的次数。 为什么?,因为我们不想为以0开头的数字计算0。例如,您不想在数字0、01、02、03等上进行计数。

通过减去ab的解,可以很容易地将解扩展到从ba - 1的范围内:

int main()
{
  long long a, b;
  // Range and digit
  scanf("%lld %lld", &a, &b, &digit);
  printf("%lld ", cntdigit(b, i) - cntdigit(a-1, i));
  return 0;
}

如果您有兴趣,可以在SPOJ

上测试此问题的一般情况的解决方案