网教10. 琪露诺的完美算数教室——⑨的统计I
来源:互联网 发布:蓝桥物流软件 编辑:程序博客网 时间:2024/05/21 22:53
众所周知,琪露诺(チルノ,Cirno)是幻想郷 (げんそうきょう)中首屈一指的天才,可以说⑨就是她的代名词。
然而如今,她遇到了一个和⑨有关的难题。你能帮助她么?
题目是这样的,给出两个数 a 和 b (0 <= a <= b <= 10^10000),求 a 到 b 之间(包括a和b)的数字中,有多少个数字是包含9的(例如 19,910 等都是包含9的数字)。
输入
第一行为一个数字 T (0 < T <= 100) 表示数据组数。
之后的 T 行,每行包含两个数 a 和 b (0 <= a <= b <= 10^10000)。
输出
对每组数据输入,输出一个数字,表示 a 到 b 之间的数字中(包括a和b),有多少个数字是包含9的。(注意:答案可能很大)
测试输入 期待的输出 时间限制 内存限制 额外进程
- 1↵
- 0 9↵
- 1↵
感觉这个题挺难的,题目写的很简单,但是思考量非常大。看了好几个博客问了几个人终于才弄明白。
首先要知道:从0到10^n一共有10^n-9^n个含9的数,在遇到9之前就一直这样算,遇到9之后就直接加上9之后的那些数即可。
比如13012958就是求10000000的9+3000000的9+10000的9+2000的9+900的9+58(900到957,一共是58个数)
也就是先从前往后走,在遇到9之前算(10^n-9^n)*a,遇到9之后直接加(也就还是a*10^n,就不用减9^n了)
由于数据很大,所以用很多个int数组来存,最后逐一输出,除了第一个之外其他的数组在输出的时候都要补前缀0.数据有10^10000,而int只存10^8,所以开1300个int数组就够储存的了。
还有要注意的是大数相加相减和相乘,这里要记得取模进位。
AC代码:
#include<stdio.h> #include<string.h> #define mod 100000000 //因为int是有精度范围的,所以加一个mod以防止爆int,最后输出的时候再逐个输出 #define last 4000 //last是假定的答案最后一位,一开始开太大了就T了 TAT char start[10005], end[10005]; int res1[4005], res2[4005], res[4005]; void add(int a[], int ak) { int i; a[last] += ak; for (i = last; i >= 0; i--) { if (a[i] >= mod) { a[i] = a[i]-mod; a[i - 1]++; }//进位 else break; } } void multi(int a[], int ak) { int i, k; int j = 0; while (!a[j]) j++;//找到非0的第一位 for (i = last; i >= j; i--) a[i] = a[i]*ak; k = 0; for (i = last; i >= j - 2; i--) { a[i] += k; k = a[i] / mod; a[i] = a[i] % mod; }//进位 } void minus(int a1[], int a2[], int a3[]) { int i; for (i = last; i >= 0; i--) { a1[i] = a2[i] - a3[i]; } for (i = last; i >0; i--) { if (a1[i] < 0) { a1[i - 1] --; a1[i] += mod; } } }//a1是结果数组 int ans1[10005] = { 0 }, ans2[10005];//分别储存乘10和9 void fun(char a[],int b) { memset(ans1, 0, sizeof(ans1)); memset(ans2, 0, sizeof(ans2)); int i; int c[10005]; for (i = 0; i < strlen(a); i++) c[i] = a[i] - '0'; ans1[last] = c[0];//给第一个元素赋初值 ans2[last] = c[0]; int flag = 0; if (c[0] == 9) flag = 1; for (i = 1; i < strlen(a); i++) { multi(ans1, 10); add(ans1, c[i]);//每次都把ans1乘10再把a加到ans1里 multi(ans2, 9);//把ans2乘9(即求9^n) if (!flag) add(ans2, c[i]);//如果前面的数里面有9,就不用再加了 if (c[i] == 9) flag = 1; } if (b == 1) minus(res1, ans1, ans2);//最后再把它们减一下 else minus(res2, ans1, ans2); } int main() { int t; scanf("%d", &t); while (t--) { scanf("%s%s", start, end); int len1, len2; len1 = strlen(start); len2 = strlen(end); fun(start, 1); fun(end, 2); minus(res, res2, res1); int i; for (i = 0; i < len2;i++) if (end[i] == '9') { res[last]++;//说明最后一个没有算上 break; } i = last; while (res[i] >= mod) { res[i - 1]++; res[i] -= mod; i--; } i = 0; while (!res[i]&&i<=last) i++;//把前缀的0全都跳过去 printf("%d", res[i]);//第一个不用补0 i++; while (i <= last) { printf("%08d", res[i]);//res数组中不足8位的就补0 i++; } printf("\n"); } return 0; }
- 1↵
- 0 9↵
- 1↵
- 网教10. 琪露诺的完美算数教室——⑨的统计I
- BITCS2016程序设计 | 10. 琪露诺的完美算数教室——⑨的统计I
- 2013-BIT程序设计 9.琪露诺的完美算数教室——⑨的统计I -- 高精度
- 琪露诺的完美算数教室——⑨的统计I
- 2393: Cirno的完美算数教室
- 【BZOJ2393】Cirno的完美算数教室
- bzoj2393: Cirno的完美算数教室
- [BZOJ 2393]Cirno的完美算数教室
- bzoj2393 Cirno的完美算数教室
- 【bzoj2393】Cirno的完美算数教室
- 琪露诺的算数教室——解题报告
- Cirno的完美算数教室(容斥)
- 【bzoj2393】 Cirno的完美算数教室 容斥原理
- 【bzoj2393】【Cirno的完美算数教室】【搜索+容斥原理】
- 2393: Cirno的完美算数教室 容斥原理
- BZOJ2393: Cirno的完美算数教室 容斥原理
- bzoj2396 Cirno的完美算数教室 容斥
- BZOJ 2393: Cirno的完美算数教室 容斥原理
- 【bzoj1096】[ZJOI2007]仓库建设
- Revit开发之备份文件数量
- Android网络状态之----ConnectivityManager
- C语言中类型转换问题
- Mac Intellij IDEA修改maven配置
- 网教10. 琪露诺的完美算数教室——⑨的统计I
- 无符号数除以2的幂
- node-haystack Episode 6: Data Structure And Constants
- SSM框架+Log4j框架搭建
- iOS 中Touch ID(指纹识别技术) 的使用
- Android安全加密:非对称加密
- 神经概率语言模型--吴立德教授深度学习课程笔记(十)
- React+Webpack快速上手指南
- 51nod1066Bash游戏