AcWing 338. 计数问题
原题链接
中等
作者:
henhen敲
,
2020-04-25 11:00:49
,
所有人可见
,
阅读 571
y老的思路 自己实现一下 以后方便记忆
如统计数字abcdefg中 我们以数字1为例 (可以是任何数字)出现的次数 复杂度O(n*位数) 可以在每一位上统计1的次数
若现在正在统计第四位上 出现1的次数
xxxdyyy
默认执行该步 xxx属于 000~abc-1 d等于1时 则 yyy 可以是 0
000~999 则一共有 abc*1000次
xxx=abc时 分情况讨论
(1)d<1,此时1在第四位出现的次数为0
(2)d=1,只有 yyy 000~efg
(3)d>1, yyy可取 000~999
最终结果为上述总和
这里要注意边界问题
(1)当统计最高位时 应该注意 最高位没有左侧xxx 所以统计最高位时 没有上面的默认步
(2)统计0出现的次数时 应该是1~abc-1 位 比正常的少1
import java.io.*;
import java.util.*;
class Main{
static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static int nextInt() throws Exception{
in.nextToken();
return (int)in.nval;
}
static int power10(int x){
int res = 1;
while(x--!=0) res *= 10;
return res;
}
static int get(List<Integer>nums, int l, int r){
int res = 0;
for(int i=r; i>=l; i--)
res = res*10 + nums.get(i);
return res;
}
static int count(int n, int x){
List<Integer> nums = new ArrayList<>(10);
while(n!=0){
nums.add(n % 10);
n /= 10;
}
n = nums.size();
int res = 0;
int m = (x==0)?1:0;//当统计0时 最高位不能为0 所以只统计到次最高位
for(int i=0; i<n-m; i++){
if(i<n-1){
res += get(nums, i+1, n-1) * power10(i);
if(x==0) res -= power10(i);//统计0时 应该从1~abc-1 所以get应该减一
}
if(nums.get(i)>x) res += power10(i);
if(nums.get(i)==x) res += get(nums, 0, i-1) + 1;
}
return res;
}
public static void main(String[] args) throws Exception{
int a, b;
a = nextInt(); b = nextInt();
while(a!=0&&b!=0){
if(a>b){
int temp = a;
a = b;
b = temp;
}
for(int i=0; i<10; i++)
out.print(count(b, i) - count(a-1, i) + " ");
out.println("");
a = nextInt(); b = nextInt();
}
out.close();
}
}