zoukankan      html  css  js  c++  java
  • UVA 1640 The Counting Problem

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

    题目

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

    题解

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

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

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

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

    考虑百位,那么出现的情况是$oxed{1}99simoxed{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('
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    正则表达式、常用的匹配总结
    已知IP地址,如何计算其子网掩码,默认网关地址,网络地址等。
    暑假作业日总结
    暑假作业日总结
    暑假作业日总结
    暑假作业日总结
    暑假作业日总结
    暑假作业日总结
    暑假作业日总结
    暑假作业日总结
  • 原文地址:https://www.cnblogs.com/sahdsg/p/11869625.html
Copyright © 2011-2022 走看看