Uva(11038)(How|Uva(11038)(How Many O's? )

【Uva(11038)(How|Uva(11038)(How Many O's? )】链接:https://vjudge.net/problem/UVA-11038
思路:虽然最后代码非常短,但是我觉得里面蕴含的巧妙的思想远远不止这些,首先算0个数肯定不能硬来,也不太好分区间算容易产生重叠,正解的方法是枚举原数的各个位置的数字,如果不为0,则该位前面的数字pow (10,后面数字个数)就是当前位为0的方案总数(例如12139,枚举第三位为0,方案书为12100),如果为0,则需要(前面-1)pow (10,后面数字个数)+后面+1(例如12039,当枚举第三位时,此时的个位为前面的11种后面的100种+39+1),这时最妙的来了,这样不会重叠或者说不是根本没有计算0有多少个吗,我们枚举的是当前为0的数的个数,试想一个数有很多个0,那么他的每个位置都会被枚举一次,从而这个数会被计算他0的个数那么多次,刚好就是我们要算的一共有多少0,这个实在是太妙了!!!!
代码:

#include using namespace std; long long n,m; long long num(long long x){ long long res = 1,ans = 0,xx=1; if(x<0)return 0; while(x>=10){ long long mid = x%10; x/=10; if(mid)res+=x*xx; else res+=(x-1)*xx+(ans+1); ans = ans+mid*xx; xx*=10; } return res; }int main(){ while(scanf("%lld%lld",&n,&m)&&n!=-1){ printf("%lld\n",num(m)-num(n-1)); } return 0; }

    推荐阅读