大数阶乘的其他方法
2016-04-19 20:47
387 查看
HDU 1042N!的其他方法
1;这题上次就写过一篇文档,然而这次又来再说这题。主要是觉得上次那方法不能普遍适用于大数问题,所以改了一下代码。经历也是曲折啊?弄捣了好久。
2;先说一下这题还有一个小知识点那就是0的阶乘是1.题目的范围就是从0<=n<=10000;包括了0.所以要考虑0阶乘的问题。
3;方法就是一个数组元素只存一位数。然而里面却有好多要注意的。
(1;先说定义变量的问题吧,如果定义longlong形数组变量。则会超时。因此要用int。至于原因我也不太确定,网上说是存储空间大些,在矩阵乘法的时候多进行了一下模,则时间就要久一点。因此要注意一下。
(2;这次打的代码与上次还有一点不同的是,这次是先将数组元素全部乘完然后在单独进行进位。当然我也试过如果存一位一边乘积一边进位会出现大问题的。到后面的乘法根本就对不上号了。因此只能进行单独的进位了。然而没有超时,因此这个也可以变成大数问题的一个模板吧。
(3;注意这种单独进位的要怎么增加数组元素呢。初始化是1,那怎么增加呢,什么时候增加呢?当if(a[t] > 9)就进行t++;只有达到这种情况时才能增加t;
(4;只存一位那么肯定会存在一下会有多次进位的情况,则进位那里也需要一个循环了。
应该是这个样子;
for(k = j; k <= t; k++)
{
if(a[t] >9)
{
t++;
}
a[k+1] += a[k]/10;//这里可以是多位数反正还有下次的。
a[k] = a[k]%10;
}
懂了吗?里面有一点点递推的味道。
(5;剩下的就是输出问题了。要注意n=0的时候的输出情况。至于其余情况就是反过来输出也就一样了,并且只保存一位数的输出就是%d就OK了。
然后就可以摆代码了吧。
#include<stdio.h>
#include<string.h>
int a[10000000];
int main()
{
int n, i, j, k, t;//如果定义成long long就会超时;而int就ac了;
while(scanf("%d",&n) != EOF)
{
memset(a, 0, sizeof(a));
a[0] = 1;
a[1] = 1;
t = 1;
if(n == 0)
{
printf("1\n");
continue;
}
for(i = 1; i <= n; i++)
{
for(j = 1; j <= t; j++)
{
a[j] *= i;
}
for(j = 1; j <= t; j++)
{
if(a[j] > 9)
{
for(k = j; k <= t; k++)
{
if(a[t] >9)
{
t++;
}
a[k+1] += a[k]/10;
a[k] = a[k]%10;
}
}
}
}
printf("%d",a[t]);
for(i = t-1; i >= 1; i--){
printf("%d",a[i]);
}
printf("\n");
}
}
1;这题上次就写过一篇文档,然而这次又来再说这题。主要是觉得上次那方法不能普遍适用于大数问题,所以改了一下代码。经历也是曲折啊?弄捣了好久。
2;先说一下这题还有一个小知识点那就是0的阶乘是1.题目的范围就是从0<=n<=10000;包括了0.所以要考虑0阶乘的问题。
3;方法就是一个数组元素只存一位数。然而里面却有好多要注意的。
(1;先说定义变量的问题吧,如果定义longlong形数组变量。则会超时。因此要用int。至于原因我也不太确定,网上说是存储空间大些,在矩阵乘法的时候多进行了一下模,则时间就要久一点。因此要注意一下。
(2;这次打的代码与上次还有一点不同的是,这次是先将数组元素全部乘完然后在单独进行进位。当然我也试过如果存一位一边乘积一边进位会出现大问题的。到后面的乘法根本就对不上号了。因此只能进行单独的进位了。然而没有超时,因此这个也可以变成大数问题的一个模板吧。
(3;注意这种单独进位的要怎么增加数组元素呢。初始化是1,那怎么增加呢,什么时候增加呢?当if(a[t] > 9)就进行t++;只有达到这种情况时才能增加t;
(4;只存一位那么肯定会存在一下会有多次进位的情况,则进位那里也需要一个循环了。
应该是这个样子;
for(k = j; k <= t; k++)
{
if(a[t] >9)
{
t++;
}
a[k+1] += a[k]/10;//这里可以是多位数反正还有下次的。
a[k] = a[k]%10;
}
懂了吗?里面有一点点递推的味道。
(5;剩下的就是输出问题了。要注意n=0的时候的输出情况。至于其余情况就是反过来输出也就一样了,并且只保存一位数的输出就是%d就OK了。
然后就可以摆代码了吧。
#include<stdio.h>
#include<string.h>
int a[10000000];
int main()
{
int n, i, j, k, t;//如果定义成long long就会超时;而int就ac了;
while(scanf("%d",&n) != EOF)
{
memset(a, 0, sizeof(a));
a[0] = 1;
a[1] = 1;
t = 1;
if(n == 0)
{
printf("1\n");
continue;
}
for(i = 1; i <= n; i++)
{
for(j = 1; j <= t; j++)
{
a[j] *= i;
}
for(j = 1; j <= t; j++)
{
if(a[j] > 9)
{
for(k = j; k <= t; k++)
{
if(a[t] >9)
{
t++;
}
a[k+1] += a[k]/10;
a[k] = a[k]%10;
}
}
}
}
printf("%d",a[t]);
for(i = t-1; i >= 1; i--){
printf("%d",a[i]);
}
printf("\n");
}
}
相关文章推荐
- springmvc处理上传图片代码(校验图片尺寸、图片大小)
- DOS下sqlite3乱码问题
- Android 进程增加存活率
- UVA 111 History Grading
- Border属性的各种变化
- 在Isight软件里如何调用matlab子程序?
- Mybatis最入门---ResultMaps高级用法(上)
- struts2的搜索顺序:与理论不一致
- Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
- Hadoop(二)实现SSH互联
- java 缓存--查成绩
- 个人总结-mysql错误
- 班级派团队项目小计(二)
- cocoapod-使用cocoapod安装AFNetworking3.0
- python list排序
- UVA 11039 Building Designing
- 关于Xcode的错误分析和处理
- [JAVA修炼之路八]-java包Concurrent包-atomic
- while, do-while ,switch···case语句的学习与运用
- leetcode——33——Search in Rotated Sorted Array