用java统计页码到n中0-9出现的次数,页码统计

17

#include

using namespace std;

int count(int n, int x) {

int res = 0, j;

for (int i = 1; j = n / i; i *= 10) {

int high = j / 10;

if (x == 0) {

if (high)

high--;

else

break;

}

res += high * i;

int tem = j % 10;

if (tem > x)

res += i;

else if (tem == x)

res += n - j * i + 1;

}

return res;

}

int main(){

int n;

while (cin >> n){

cout << count(n, 0);

for (int i = 1; i <= 9; i++)

cout << " " << count(n, i);

}

return 0;

}

//最优的解法了,时间复杂度O(log10(N)),以10为底N的对数,也就是N的位数

编辑于 2017-03-09 18:33:39

回复(7)

8

2位数的情况:

N=13,个位数出现的1的次数为2,分别为1和11,十位数出现1的次数为4,分别为10,11,12,13,所以f(N) = 2+4。

N=23,个位数出现的1的次数为3,分别为1,11,21,十位数出现1的次数为10,分别为10~19,f(N)=3+10。

由此我们发现,个位数出现1的次数不仅和个位数有关,和十位数也有关,如果个位数大于等于1,则个位数出现1的次数为十位数的数字加1;如果个位数为0,个位数出现1的次数等于十位数数字。而十位数上出现1的次数也不仅和十位数相关,也和个位数相关:如果十位数字等于1,则十位数上出现1的次数为个位数的数字加1,假如十位数大于1,则十位数上出现1的次数为10。

3位数的情况:

N=123

个位出现1的个数为13:1,11,21,…,91,101,111,121

十位出现1的个数为20:10~19,110~119

百位出现1的个数为24:100~123

我们可以继续分析4位数,5位数,推导出下面一般情况:

假设N,我们要计算百位上出现1的次数,将由三部分决定:百位上的数字,百位以上的数字,百位一下的数字。

如果百位上的数字为0,则百位上出现1的次数仅由更高位决定,比如12013,百位出现1的情况为100~199,1100~1199,2100~2199,…,11100~11199,共1200个。等于更高位数字乘以当前位数,即12 * 100。

如果百位上的数字大于1,则百位上出现1的次数仅由更高位决定,比如12213,百位出现1的情况为100~199,1100~1199,2100~2199,…,11100~11199,12100~12199共1300个。等于更高位数字加1乘以当前位数,即(12 + 1)*100。

如果百位上的数字为1,则百位上出现1的次数不仅受更高位影响,还受低位影响。例如12113,受高位影响出现1的情况:100~199,1100~1199,2100~2199,…,11100~11199,共1200个,但它还受低位影响,出现1的情况是12100~12113,共14个,等于低位数字13+1。

public static long getFactorCount(long num,byte factor){

long count=0;

long current=0,next=0,before=0;

long i=1;

while((num/i)!=0){

current=(num/i)%10;

next=num/(i*10);

before=num-(num/i)*i;

if(current

count+=next*i;

}

else if(current==factor){

count+=next*i+before+1;

}

else if(current>factor)count+=(next+1)*i;

i*=10;

}

return count;

}

编辑于 2017-04-02 10:56:59

回复(4)

1

#include

int main()

{

int i,n,j,temp = 0,a = 1,b = 10;

int count[10] = {0};

scanf("%d",&n);

while(n >= a)

{

for(j = 0;j < 10;j++)

{

temp = temp + n/b;

if(j < n%b/a)

temp = temp + 1;

count[j] = count[j] + temp * a;

temp = 0;

}

for(i = 0;i <= n%b/a;i++)

{

if(i == n%b/a)

count[i] = count[i] + n % a + 1;

}

count[0] = count[0] - a;

a = a * 10;

b = b * 10;

}

for(i = 0;i < 10;i++)

{

printf("%d",count[i]);

if(9-i)

printf(" ");

}

return 0;

}

发表于 2017-09-26 17:41:06

回复(0)

1

//从各位开始对n的每一位进行判断

#include

#include

using namespace std;

int getCount(int n, int t)

{

if (n < 1 || t < 0)

return -1;

int cnt = 0,len=0;

int k = 1;

int j = n;

while (j)

{

j = j / 10;

++len;

}

for (int i = 0; i < len; ++i)

{

if (t>0)

{

if ((n / k) % 10 < t)

cnt += (n / (k*10))*k;

else if ((n / k) % 10 == t)

cnt += (n / (k * 10))*k + n%k + 1;

else

cnt += (n / (k * 10) + 1)*k;

}

else

{

if ((n / k) % 10 == t)

cnt += (n / (k * 10) - 1)*k + n % k + 1;

else

cnt += (n / (k * 10))*k;

}

k = k * 10;

}

return cnt;

}

int main()

{

int n;

cin >> n;

for (int i = 0; i < 10; ++i)

{

if (i == 0)

cout << getCount(n, i);

else

cout << " " << getCount(n, i);

}

cout << endl;

return 0;

}

发表于 2017-07-27 18:59:48

回复(0)

1

逐位求解每个数字该位上出现的次数,累加到数组中。

#include

using namespace std;

int main(){

int n,i,j;

cin>>n;

int tmp[10]={0};

for(i=1;j=n/i;i*=10){

int high=j/10;

int res=j%10;

for(int k=0;k<10;k++)

tmp[k]+=i*high;

for(int k=0;k

tmp[k]+=i;

tmp[res]+=n%i+1;

tmp[0]=tmp[0]-i/10;//0的特殊处理

}

tmp[0]=tmp[0]-i/10;

for(int i=0;i<9;i++)

cout<

cout<

return 0;

}

发表于 2017-04-19 14:35:43

回复(0)

1

def find(num):

# 计算每个数字, 在每一位上出现的次数.

res = [0] * 10 # 结果

digit = 1 # 个位

while True:

low = num % digit

cur = (num % (10 * digit)) / digit

high = num / (10 * digit) # 将数字分割, 例如 digit为100时, 表示百位. 12345 将有 high = 12, cur = 3, low = 45

if cur == 0 and high == 0:

break

for i in range(10): # 从0到9, 计算i在digit位出现的次数.

if i < cur:

if i == 0: # 这里主要是因为 0 不能作为数字的开头.

res[i] += high * digit

else:

res[i] += (high+1) * digit

elif i == cur:

if i==0:

res[i] += (high-1) * digit + low + 1

else:

res[i] += high * digit + low + 1

else:

if i == 0:

res[i] += (high-1) * digit

else:

res[i] += high * digit

digit *= 10 # 下一位

return res

num = int(raw_input())

res = find(num)

print ' '.join(map(str, res))

发表于 2017-04-01 00:44:05

回复(0)

3

//提供一种简单的思路

public class Main {

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

String str = "0123456789";

while(scanner.hasNext()){

int n = scanner.nextInt();

int[] nums = new int[10];

for(int i=1;i<=n;i++){

char[] c = new String(i+"").toCharArray();

for(int j=0;j

nums[str.indexOf(c[j])] +=1;

}

}

for(int i=0;i

System.out.print(nums[i]+" ");

}

System.out.println(nums[9]);

}

}

}

编辑于 2017-03-09 15:12:04

回复(4)

0

def count_digit(n, x):

high = n // 10

cur = n % 10

low = 0

digit = 1

res = 0

while high != 0 or cur != 0:

if 0 <= cur < x:

res += high * digit

elif cur == x:

if x == 0:

res += (high - 1) * digit + low + 1

else:

res += high * digit + low + 1

elif cur > x:

if x == 0:

res += high * digit

else:

res += (high + 1) * digit

low += cur * digit

cur = high % 10

high //= 10

digit *= 10

return res

if __name__ == '__main__':

n = int(input())

for i in range(9):

print(count_digit(n, i), end=' ')

print(count_digit(n, 9), end='')

发表于 2021-03-13 13:42:18

回复(0)

0

#include 

#include 

#include

using namespace std;

int main()

{

int a[10] = { 0,0,0,0,0,0,0,0,0,0 };

int num;

cin >> num;

for (int i = 0; i <= 9; i++)

{

int digit = 1;

int temp = 0;

while (num / digit != 0)

{

int qian = num / 10 / digit;

int cur = (num / digit) % 10;

int hou = num % digit;

if (cur > i)

{

if (i != 0)

temp += (qian + 1) * digit;

else temp += qian * digit;

}

else if (cur == i)

{

if (i != 0)

temp += qian * digit + hou + 1;

else temp += (qian - 1) * digit + hou + 1;

}

else

{

temp += qian * digit;

}

digit *= 10;

}

a[i] = temp;

}

cout <

for (int i = 1; i <= 9; i++)

{

cout <

}

}

发表于 2020-08-04 11:16:02

回复(0)

0

def pcount(x, n):

a, b, c, i, m = 1, 0, 0, 1, 0

while a:

k = x // i

a = k // 10

b = k % 10

c = x % i

if n > b:

m += a * i

elif n == b:

m += ((a-bool(n==0)) * i + c + 1)

else:

m += (a + bool(n)) * i

i *=10

return m

inum = int(input())

onum = str(pcount(inum, 0))

for j in range(1, 10):

onum += (' ' + str(pcount(inum, j)))

print(onum)

编辑于 2020-04-07 16:26:49

回复(0)

0

import java.util.*;

public class Main {

public static void main(String[] ags) {

Scanner in = new Scanner(System.in);

long n = in.nextLong();

in.close();

long[] numbers = new long[11];

long i =0;

for( i=1; n/i!=0;i=i*10) {

for(int j=1; j<10;j++) {

/**

*(n%(i*10))/i 是计算当前位置上的数,看前面同学的算法,分别计算before,current,after似乎更容易

*/

if(j

numbers[j]=numbers[j]+(n/(i*10) + 1)*i;

}

else if(j==((n%(i*10))/i)) {

numbers[j]=numbers[j]+(n/(i*10))*i+n%i+1;

}

else numbers[j]=numbers[j]+(n/(i*10))*i;;

}

if(((n%(i*10))/i)==0) {

numbers[0]=numbers[0]+(n/(i*10)-1)*i+n%i+1;

}

else {

numbers[0]=numbers[0]+(n/(i*10))*i;

}

}

for(int j =0; j<9; j++) {

System.out.print(numbers[j] + " ");

}

System.out.print(numbers[9]);

}

} 就这么个题,从早上写到晚上,脑子里像一团浆糊

发表于 2020-04-05 06:57:05

回复(0)

0

import java.util.Scanner;

/*

* 本文内容主要参考:https://blog.csdn.net/zjkc050818/article/details/66474150

* 关键之处在于针对不同的位置分别统计可能出现的的次数,然后汇总返回

* */

public class Main {

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

while (scanner.hasNext()) {

int n = scanner.nextInt();

int[] count = new int[10];

help(count, n);

System.out.print(count[0]);

for (int i = 1; i < 10; i++) {

System.out.print(" " + count[i]);

}

System.out.println();

}

}

private static void help(int[] count, int n) {

for (int i = 1; n / i >= 1; i *= 10) {

int before = n / (i * 10);

int current = n % (i * 10) / i;

int after = n % i;

// 针对0进行特殊处理

if (current == 0) {

count[0] += (before - 1) * i + after + 1;

} else {

count[0] += before * i;

}

// 对于1-9的元素进行统计

for (int j = 1; j < 10; j++) {

if (j < current) {

// 对于0这种情况需要增加1处理

count[j] += (1 + before) * i;

} else if (j == current) {

count[j] += before * i + after + 1;

} else {

count[j] += before * i;

}

}

}

}

}

发表于 2018-04-15 19:02:06

回复(0)

0

/*

思路:对整数n进行取位运算(自己瞎起的名字,意思是取出个位、十位...)

比较当前位和需要统计的数字,寻找规律如下:

(i表示当前的位数,i=10表示比较十位数字;

next表示当前位的后几位数字,before表示当前位的前几位数字

例如:n=123456,i=100,则当前位为百位数字4,next表示123,before表示56)

当统计数字为0时:

1> 当前位==0: count += (next - 1) * i + num % i +1;

2> 当前位!=0: count += next * i;

当统计数字不为0时:

1> 当前位 > 统计数字: count += (next+1)*i;

2> 当前位 = 统计数字: count += next*i + before + 1;

3> 当前位 < 统计数字: count += next*i;

*/

//代码如下:

import java.util.Scanner;

public class Main{

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

long n = scanner.nextLong();

for (byte i = 0; i < 10; i++) {

System.out.print(getCount(n, i));

if (i != 9) {

System.out.print(" ");

}

}

scanner.close();

}

private static long getCount(long num, byte factor) {

long count = 0;

long current = 0, next = 0, before = 0;

long i = 1;

while ((num / i) != 0) {

current = (num / i) % 10;// 取出第几位的数字

next = num / (i * 10);// 得到current的高位数字

before = num - (num / i) * i;// 得到current的低位数字

// 比较current和factor的大小

if (factor != 0) {

if (current > factor)

count += (next + 1) * i;

else if (current == factor)

count += next * i + before + 1;

else if (current < factor)

count += next * i;

} else if (factor == 0) {

if ((num / i) % 10 == factor)

count += (next - 1) * i + num % i + 1;

else

count += next * i;

}

i *= 10;

}

return count;

}

}

发表于 2018-02-02 23:22:49

回复(0)

0

from collections import Counter

Counter(''.join([str(x) for x in range(1, N)]))

发表于 2017-11-26 17:25:24

回复(0)

0

#用python字典,代码比较简单

defpage(n):

resultDict = {} fori inrange(1,n+1): forn instr(i): ifn inresultDict:

resultDict[n]+=1else:

resultDict[n]=1numList = list(resultDict.keys())

numList.sort() forr innumList: ifr != "9": print(resultDict[r],end=" ") else: print(resultDict[r])

page(999)

发表于 2017-11-09 14:51:32

回复(0)

0

/**

* 时间复杂度是O(n x log10(n))

* */

public static int[] countOfNumber(int number) {

int[] resultArray = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

if (number < 1) {

return resultArray;

}

for (int i = 1; i < number + 1; i++) {

String iString = String.valueOf(i);

for (int j = 0; j < iString.length(); j++) {

String jString = iString.substring(j, j + 1);

int key = Integer.parseInt(jString);

int value = resultArray[key];

resultArray[key] = value + 1;

}

}

return resultArray;

}

编辑于 2017-11-04 16:55:38

回复(0)

0

import string

def count(number, c_list):

next_number = number -1

if 1 == number:

c_list[1] += 1

return

while 0 != number:

c_list[number%10] += 1

number = number/10

count(next_number, c_list)

if __name__ == '__main__':

input_num = string.atoi(raw_input())

c_list = [0,0,0,0,0,0,0,0,0,0]

count(input_num, c_list)

print ' '.join([str(a) for a in c_list])

发表于 2017-11-02 16:26:35

回复(0)

0

#include

using namespace std;

int digitCount(long num, short digit) {

int i = 1, count = 0;

while (num / i > 0) {

long before = num / (i * 10);

if (digit == 0) { //对于0要特殊处理

before--;

}

long after = num - num / i * i;

short current = num / i % 10;

if (current == digit) {

count += before * i + after + 1;

} else if (current > digit) {

count += (before + 1) * i;

} else if (current < digit) {

count += before * i;

}

i *= 10;

}

return count;

}

int main(int argc, const char * argv[]) {

long num;

cin >> num;

for (int i = 0; i < 10; i++) {

int k = digitCount(num, i);

cout << k;

if (i != 9) {

cout << ' ';

}

}

return 0;

}

发表于 2017-10-23 17:23:06

回复(0)

0

参考博客:统计页码

发表于 2017-10-05 15:09:20

回复(0)

0

不确定有没有bug, 例子上的输出通过。有点儿动态规划的意思,

每遇到一个数字,把每一位提取出来,累加到该数字之前的结果上。

看了其他人的回答,测试 900000000,输出为

708888897

820000000

820000000

820000000

820000000

820000000

820000000

820000000

820000000

720000001

public static void calculate(int n) {

int[] numbers = new int[10]; for (int i = 1; i<=n; i++) {

int k = i; do {

numbers[k % 10]++; k /= 10;

} while (k > 0);

}

for (int number : numbers) {

System.out.println(number + " "); }

}

编辑于 2017-09-18 14:45:19

回复(0)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值