标签:scanf eve while lse color src 统计 class char
就是统计1~n中出现的各个数字的次数,当然是在16进制下。
不过有个区间问题的小技巧,统计从 [x,y] 可以转换成 从 [1,y] 减去 [1,x-1]。
不过要分类讨论一下,因为有可能会出现溢出,从ffffffff +1 得到 00000000 就是溢出了。
因为 n < 1e9 所以只会溢出一次。
#include<cstdio> #include<cmath> #include<cctype> const int cost[] = {6,2,5,5,4,5,6,3, 7,6,6,5,4,5,5,4}; long long solve(long long n, int k) { long long i = 1; // 位数 long long cnt = 0; long long low = 0; long long tmp = n; while(n) { long long t = n % 16; n /= 16; low = tmp % i; if(t < k) { cnt += n*i; } else if(t > k) { cnt += (1+n)*i; } else { cnt += n*i; cnt += low+1; } i *= 16; } return cnt; } int Hex(char c){ if(isdigit(c)) return c-‘0‘; return c - ‘A‘ + 10; } int main() { int t; scanf("%d",&t); for(int i=0;i<t;i++){ long long n; long long x=0; char str[15]; scanf("%lld%s",&n,str); for(int i=0;i<8;i++) x = (x<<4) + Hex(str[i]); long long cnt = 0; long long ans = 0; if((n-1)+x <= 4294967295ll){ // 没有溢出 long long tmp; for(int i=1;i<16;i++){ tmp = solve((n-1ll)+x,i); cnt += tmp; ans += tmp*cost[i]; } for(int i=1;i<16;i++){ tmp = solve(x-1,i); cnt -= tmp; ans -= tmp*cost[i]; } ans += (n*8-cnt)*cost[0]; }else { long long tmp; for(int i=1;i<16;i++){ tmp = solve(4294967295ll,i); cnt += tmp; ans += tmp*cost[i]; } for(int i=1;i<16;i++){ tmp = solve(x-1,i); cnt -= tmp; ans -= tmp*cost[i]; } for(int i=1;i<16;i++){ tmp = solve((n-2ll)+x-4294967295ll,i); cnt += tmp; ans += tmp*cost[i]; } ans += (n*8-cnt)*cost[0]; } printf("%lld\n",ans); } return 0; }
标签:scanf eve while lse color src 统计 class char
原文地址:https://www.cnblogs.com/kongbb/p/10702004.html