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)