Sicily1020-大数求余算法及优化
Github最终优化代码: https://github.com/laiy/Datastructure-Algorithm/blob/master/sicily/1020.c
题目如下:
1020. Big Integer
Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
Long long ago, there was a super computer that could deal with VeryLongIntegers(no VeryLongInteger will be negative). Do you know how this computer stores the VeryLongIntegers? This computer has a set of n positive integers: b1,b2,...,bn, which is called a basis for the computer.
The basis satisfies two properties:
1) 1 < bi <= 1000 (1 <= i <= n),
2) gcd(bi,bj) = 1 (1 <= i,j <= n, i ≠ j).
Let M = b1*b2*...*bn
Given an integer x, which is nonegative and less than M, the ordered n-tuples (x mod b1, x mod b2, ..., x mod bn), which is called the representation of x, will be put into the computer.
Input
The input consists of T test cases. The number of test cases (T) is given in the first line of the input.
Each test case contains three lines.
The first line contains an integer n(<=100).
The second line contains n integers: b1,b2,...,bn, which is the basis of the computer.
The third line contains a single VeryLongInteger x.
Each VeryLongInteger will be 400 or fewer characters in length, and will only contain digits (no VeryLongInteger will be negative).
Output
For each test case, print exactly one line -- the representation of x.
The output format is:(r1,r2,...,rn)
Sample Input
2 3
2 3 5
10 4
2 3 5 7
13
Sample Output
(0,1,0)
(1,1,3,6)
Problem Source
ZSUACM Team Member
博主刚看到这题目的时候,没怎么多想,写了个如下公式:
(x0*10^length-1 + x1*10^length-2 + ... + xlength-1*10^0)%b
=(x0*10^length-1%b + x1*10^length-2%b + ... + xlength-1*10^0%b)%b
然后这里关键是求出10^x%b出来。
注意到在求解10^x%b=(10%b * 10^x-1%b)%b,这里有一个明显的递归公式。
即,在求解10^x%b的时候已经包含了10^x-1%b的计算,而10^x-1%b的计算也会包含10^x-2%b的计算。
换句话说,我们可以实现求出需要的10^length%b,并用一个数组来保存每一步计算出来的10^x%b。
想出来的时候博主认为这样写已经效率很好了,没有重复计算,跑出来的结果是0.05s。
核心代码如下:
for (i = ; i < n; i++) {
z = b[i];
remember_arr[] = ;
temp = % z;
for (j = ; j < length; j++) {
remember_arr[j] = (temp * remember_arr[j - ]) % z;
}
result[i] = ;
count = length - ;
for (j = ; j < length; j++) {
result[i] += (((x[j] - ) % z) * remember_arr[count--]) % z;
}
result[i] %= z;
}
然后,博主google发现有一种更快的写法,即用代码模拟人手算的过程,核心代码如下:
for (j = ; j < length; j++)
result = (result * + big_number[j]) % b;
用这种写法跑的是0.03s。
最后我们来思考一下,人手算的过程的借位都是10,为什么? 因为如果借位太多计算不过来(99乘法表内的计算对人来说我们认为是可以快速计算的),但是计算机不一样,对计算机来说,xx/b的计算和xxxxxxxxxxx/b的计算是一个原子性的操作,就是说,计算机有能力借更多的位。
我们看int最大大概10^10,那么如果一次借位10^9是不是大大减少了这个运算呢?
比如说,现在有长度为36的字符串,如果按原本的写法,要借位35次,换句话说,有35个求余计算,如果把这个字符串切成4个长度为9的字符串,然后以这些碎片为单位进行运算和借位的话,只需要借位运算4次。
更改了求余运算的基本运算长度之后,性能将大幅提高,最终结果为0.00s。
核心代码如下:
num_pieces = length / + ;
pieces[] = str_to_int(p, length % );
p += length % ;
for (i = ; i < num_pieces; i++)
pieces[i] = str_to_int(p, ), p += ;
for (i = ; i < n; i++)
r[i] = calculate_result(b[i]);
函数实现如下:
int str_to_int(char *str, int l) {
result = , j = ;
while (j < l)
result = result * + str[j++] - '';
return result;
}
int calculate_result(int b) {
t = % b;
result = ;
for (j = ; j < num_pieces; j++)
result = (result * t + pieces[j] % b) % b;
return result;
}
Sicily1020-大数求余算法及优化的更多相关文章
- POJ 2635 The Embarrassed Cryptographer(大数求余)
题意:给出一个大数,这个大数由两个素数相乘得到,让我们判断是否其中一个素数比L要小,如果两个都小,输出较小的那个. 分析:大数求余的方法:针对题目中的样例,143 11,我们可以这样算,1 % 11 ...
- Project Euler 48 Self powers( 大数求余 )
题意: 项的自幂级数求和为 11 + 22 + 33 + - + 1010 = 10405071317. 求如下一千项的自幂级数求和的最后10位数字:11 + 22 + 33 + - + 100010 ...
- POJ2635-The Embarrassed Cryptographer 大数求余
题目链接:http://poj.org/problem?id=2635 题目分析: http://blog.csdn.net/lyy289065406/article/details/6648530
- (大数 求余) Large Division Light OJ 1214
Large Division Given two integers, a and b, you should check whether a is divisible by b or not. We ...
- Large Division (大数求余)
Given two integers, a and b, you should check whether a is divisible by b or not. We know that an in ...
- 大数求模 sicily 1020
Search
- 2016中国大学生程序设计竞赛 - 网络选拔赛 1001 A water problem (大数取余)
Problem Descripton Two planets named Haha and Xixi in the universe and they were created with the un ...
- 如何运用同余定理求余数【hdoj 1212 Big Number【大数求余数】】
Big Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- 高效求幂取余 算法,复杂度 log(n)
做TopCoder SRM 576 D2 L3 题目时,程序有个地方需要对一个数大量求幂并取余,导致程序运行时间很长,看了Editoral之后,发现一个超级高效的求幂并取余的算法,之前做System ...
随机推荐
- Lucene初步搜索
Lucene在创立索引后,要进行搜索查询 搜索大概需要5部, 1,读取索引. 2,查询索引. 3,匹配数据. 4,封装匹配结果. 5,获取需要的值. 语言表达能力不好,大概就是分着几部吧. /** * ...
- EDM推送
一.需求描述: 日前,做了一个发送客户账单的功能,邮件模板采用自定义,生成vm文件,保存至redis, 采用jodd-mail发送邮件,查询用户账单数据,账单明细,缓存加载模板并渲 ...
- Ubuntu1404+Django1.9+Apache2.4部署配置2配置文件设置
转载注明出处,个人博客:http://www.cnblogs.com/wdfwolf3/ Django首要的部署平台是WSGI,它是Python Web服务器和应用的标准.使用Apache和mod_w ...
- WF学习笔记(三)
Collection 集合 -AddtoCollection<T> 添加项到集合 :[AddtoCollection]可以将一个项添加到[Collection]集合中 ,[Item]属性用 ...
- java 优化
代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是, ...
- MOOC即Massive Open Online Course的缩写
A man can succeed at almost anything for which he was unlimited enthusiasm. 只要有无限的热情,一个人几乎可以在任何事情上取得 ...
- Object之克隆对象clone 和__clone()函数
在前面的PHP面向对象之对象和引用,"$b=$a"的方式复制对象传递的是对象的地址,而不是传递对象的值(内容),我们可以通过克隆对象来实现对对象的内容和引用的复制 使用传址引用的方 ...
- Python资源汇集
Python资源汇集 一 实用教程 廖雪峰网站 第一,Python教程:提供了循序渐进,重点是可操作的实用教程. 第二,Web App 项目教程.给出一个用16天完成的Python Web APP项目 ...
- 鸟哥的linux私房菜——第20章 启动流程、模块管理与loader
20.1 Linux启动流程分析 Linux启动过程: 按下开机电源后计算机硬件主动读取BIOS来加载硬件信息以及硬件系统的自我测试,之后系统会主动读取第一个可启动的设备(由BIOS设置),此时就可以 ...
- jQuery中的data方法:
向元素附加数据,然后取回该数据: $("#btn1").click(function(){ $("div").data("greeting" ...