码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 1640 The Counting Problem

时间:2019-11-15 22:28:43      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:https   swap   swa   sla   举例   lan   clu   net   nbsp   

https://vjudge.net/problem/UVA-1640

题目

给两个数字$a$,$b$,问将$[a,b]$之间的数字写成一行,数字0、1、2、3、4、5、6、7、8、9各出现多少次。$n\leqslant 10^8$,500组数据

题解

分两种情况,考虑每一位……

举个例子,如果给的数字是203,考虑1出现多少次。

考虑个位,那么出现的情况是$20\boxed{1}\sim \phantom{00}\boxed{1}$,$20-0+1$次

考虑十位,那么出现的情况是$1\boxed{1}9\sim \phantom{0}\boxed{1}0$,$19-0+1$次

考虑百位,那么出现的情况是$\boxed{1}99\sim\boxed{1}00$,$99-0+1$次

其他的情况也要考虑……这只是举例= =

AC代码

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<cassert>
#include<algorithm>
#define REP(i,a,b) for(register int i=(a); i<(b); i++)
#define REPE(i,a,b) for(register int i=(a); i<=(b); i++)
#define PERE(i,a,b) for(register int i=(a); i>=(b); i--)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...) (void)0
#endif
#define ln log
using namespace std;
typedef long long LL;
int a,b;
int f0(int x) {
	int k;
	int ans=0;
	for(int i=1; i<=x; i*=10) {
		k = x/i/10*i;
		if(k*10+i-1<=x) k+=i-1;
		else k+=x%i;

		if(k>=i) ans+=k-i+1;
	}
	return ans;
}
int f(int x, int q) {
	int k;
	int ans=0;
	for(int i=1; i*q<=x; i*=10) {
		k = x/i/10*i;
		if(k*10+i*q>x) k-=i;

		if(k*10+i*q+i-1<=x) k+=i-1;
		else k+=x%i;

		ans+=k+1;
	}
	return ans;
}
int main() {
	
	while(~scanf("%d%d", &a, &b) && a) {
		if(a>b) swap(a,b);
		printf("%d", f0(b)-f0(a-1));
		REP(i,1,10) {
			printf(" %d", f(b,i)-f(a-1,i));
		}
		putchar(‘\n‘);
	}
	return 0;
}

 

UVA 1640 The Counting Problem

标签:https   swap   swa   sla   举例   lan   clu   net   nbsp   

原文地址:https://www.cnblogs.com/sahdsg/p/11869625.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!