本文已参与「新人创作礼」活动,一起开启掘金创作之路。
蓝桥杯练习009
数列求值
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
给定数列 1, 1, 1, 3, 5, 9, 17,⋯,从第 4 项开始,每项都是前 3 项的和。
求第 20190324 项的最后 4 位数字。
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
解题思路
可以用三个变量将前三个数存下来,然后用一个变量表示三者的和,通过循环进行求解,并不断更新三个数的值,最后输出即可
代码
#include <iostream>
using namespace std;
int main()
{
int a,b,c;
int tmp;
a=1;
b=1;
c=1;
for(int i=3;i<20190324;i++){
tmp=(a+b+c)%10000;
a=b;
b=c;
c=tmp;
}
cout<<tmp<<endl;
return 0;
}
阶乘计算
题目描述
输入一个正整数 n,输出 n! 的值。n<=1000n<=1000。
这是一道高精度题目,需要处理大数。后面将会给出 C++、Java、Python 三种解决方案。
解题思路 — C++
萌新:这题我会,只要将 1\sim n1∼n 的每个数乘起来就好了。
大佬:那你算算 21!等于多少?
萌新: 我算算吼。21!=1×2×3×…×21 = 5109094217170944000021!=1×2×3×…×21=51090942171709440000。
大佬: ??你怎么算的这么快?
萌新: 因为我用了计算器…
大佬: …,那你发现什么了没有?
萌新: 5109094217170944000051090942171709440000这个数太大了,C++的unsigned long long 最大值也才2^{64}264,存不下。
大佬: 是吧,所以你的想法是美好的,只可惜C++的整型变量根本…
萌新: 哦那我可以用 __int128。
大佬: …,__int128目前还有很多OJ不支持,就算支持,那 1000!你总没办法存了吧。
萌新: em,那该怎么办?
大佬: 别急,你先回想一下你小学老师教你的乘法是什么样的?
萌新: 小学学的乘法法大概是:相同数位对齐,然后选择其中一个数的各位数字乘以另一个数,并 把相乘的结果累加…
大佬: 是的,那么你就可以模拟这个操作:
1. 定义一个大数组A[]来存大数,数组的一个元素存大数的一位。例如A[0]存个位,A[1]存十位,A[2]存百位,等等。
2. 那么A[]需要定义成多大?也就是说,1000!有多少位?可以自己估计,不过,可以用 windows 自带的计算器能直接算出来,1000! ≈ 4×10^{2567}。代码中定义一个更大的A[10000]。
3. 模拟乘法计算,处理进位:例如356×8。先计算个位的6×8,得48,其中个位的8等于 48%10=8,进位的4等于48/10=4。
见我代码中的10\sim 13行,这几行实际上是处理了两个数的乘法,请仔细分析这几行代码。
4. 按3的计算方法,计算n!。第8行的i遍历了1\sim n,计算n!。
5. 最后打印是,从最高位开始打印。先找到最高位,即第一个不等于0的数,然后从高位往最低位打印。
萌新: 了解!不过大佬,这复杂度不会太高了吗?
大佬: 当然不会,你看我代码的第8行和10行,代码共循环计算了10000×n = 10000×1000 =10000×n=10000×1000= 1千万次,正好不会超时。这也是题目为什么要你计算1000!,若计算更大的数,用这个代码就可能超时了。
代码
#include <bits/stdc++.h>
using namespace std;
int A[10000] = {0}; //存结果,注意大的静态数组要定义在全局
int main(){
int n;
cin >> n;
A[0] = 1;
for(int i = 1;i <= n;i++){
int carry = 0; //进位
for(int j = 0;j < 10000;j++){
A[j] = A[j] * i + carry;
carry = A[j] / 10;
A[j] = A[j] % 10;
}
}
int last;
for(int i = 10000 - 1;i >= 0;i--){
if (A[i] != 0){
last = i;
break;
}
}
for(int i = last; i >= 0;i--)
cout << A[i];
return 0;
}
解题思路 — Java
大佬: Java有专门的类可以直接处理大数,不需要用数组。
萌新: 蓝桥杯Java组比赛不会出这种简单大数题吧?太没有难度了。
代码
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while(in.hasNext()) {
int n = in.nextInt();
BigInteger s = new BigInteger("1");
for(int i = n; i >= 1; i--)
s = s.multiply(new BigInteger(String.valueOf(i)));
System.out.println(s);
}
}
}
解题思路 — Python
萌新&大佬: Python真好,非常好,就是好!
N = int(input())
ans = 1
for i in range(1, N+1):
ans *= i
print(ans)