算法实验课 lab1 解题报告
LAB1(共三题)
【1】

解题思路:
首先,题目大意是求出每个Fibonacci数,并用得到的Fibonacci数用(1E+9)+7来区模,并将其输出换行。(输入的N为Fibonacci下标).需要注意的点是要注意在求Fibonacci数的时候可能会产生溢出(即使使用long long 类型存储,在N等于99时也会溢出),故我采用的方法是每次计算Fibonacci数时同时取模,则因为输入的N要小于100,故不会溢出。
相关代码如下(0sec AC):
1 #include <stdio.h> 2 #include <string.h> 3 4 #define mod 1000000007 5 6 int main(void) 7 { 8 int n;// The number of test cases 9 int fib[110]; 10 while(scanf("%d",&n)!=EOF&&(n>0)){ 11 int i; 12 fib[0]=0; 13 fib[1]=1; 14 if(n>1){ 15 for(i=2;i<=n;i++){ 16 fib[i]=fib[i-1]+fib[i-2]; 17 fib[i]=fib[i]%mod; 18 } 19 } 20 printf("%d\n",fib[n]); 21 } 22 return 0; 23 24 }
【2】

解题思路:
首先,题目大意是求出每个Fibonacci数,并用得到的Fibonacci数用(1E+9)+7来区模,并将其输出换行。(输入的N为Fibonacci下标).需要注意的点是要注意在求Fibonacci数的时候可能会产生溢出(即使使用long long 类型存储,在N等于99时也会溢出),同样若是使用上一题的直接每次取模的方法,也会溢出(N小于2^31-1),所以这一题我使用的是矩阵乘法结合快速幂并同时取模的方法。
相关代码如下(0sec AC):
1 #include <stdio.h> 2 #include <math.h> 3 4 #define mod 1000000007 5 6 typedef long long LL; 7 8 /* 9 *定义一个2维的矩阵。 10 */ 11 12 struct matrix 13 { 14 LL m[2][2]; 15 }base,result; 16 17 18 /* 19 *矩阵乘法 20 */ 21 22 matrix multi(matrix a,matrix b) 23 { 24 int i,j,k; 25 matrix temp; 26 for(i=0;i<2;i++){ 27 for(j=0;j<2;j++){ 28 temp.m[i][j]=0; 29 for(k=0;k<2;k++){ 30 temp.m[i][j]+=a.m[i][k]*b.m[k][j]; 31 temp.m[i][j]=temp.m[i][j]%mod; 32 } 33 } 34 } 35 return temp; 36 } 37 38 /* 39 *快速幂算法 40 */ 41 42 LL fast_mod(LL n) 43 { 44 base.m[0][0]=0; 45 base.m[0][1]=1; 46 base.m[1][0]=1; 47 base.m[1][1]=1; 48 49 //初始化 50 result.m[0][0]=1; 51 result.m[0][1]=0; 52 result.m[1][0]=0; 53 result.m[1][1]=1; 54 55 while(n){ 56 if(n%2==1){ 57 result=multi(result,base); 58 } 59 base=multi(base,base); 60 n=n/2; 61 } 62 return result.m[0][1]; 63 } 64 65 66 int main(void) 67 { 68 LL n;// The number of test cases 69 while(scanf("%lld",&n)!=EOF&&(n>=0)&&(n<=pow(2,31)-1)){ 70 printf("%lld\n",fast_mod(n)); 71 } 72 return 0; 73 }
【3】

解题思路:
此题是要求哈夫曼树的WPL,有两种思路实现,一种是使用优先队列,一种是通过观察可知,所谓WPL就是哈夫曼树非叶子节点的值得和。
相关代码如下:
(1)优先队列实现如下:
1 #include <queue> 2 #include <iostream> 3 #include <algorithm> 4 #include <stdio.h> 5 #include <string> 6 #include <cmath> 7 #include <vector> 8 using namespace std; 9 10 struct X 11 { 12 char a; 13 int b; 14 }x; 15 16 priority_queue<int, vector<int>,greater<int> > Q; 17 18 int main(void) 19 { 20 int n; 21 while(scanf("%d",&n)!=EOF){ 22 while(Q.empty()==false){ 23 Q.pop(); 24 } 25 26 for(int i=1;i<=n;i++){ 27 cin>>x.a>>x.b; 28 Q.push(x.b); 29 } 30 int ans = 0; 31 while(Q.size()>1){ 32 int c = Q.top(); 33 Q.pop(); 34 int d = Q.top(); 35 Q.pop(); 36 ans+=c+d; 37 Q.push(c+d); 38 } 39 printf("%d\n",ans); 40 } 41 return 0; 42 }
(2)非叶子节点实现如下:
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 int main(void) 6 { 7 int n; 8 while(cin>>n){ 9 int sum=0; 10 int a[n]; 11 char b[n]; 12 for(int i=0;i<n;i++) 13 cin>>b[n]>>a[i]; 14 for(int i=1;i<n;i++) 15 { 16 sort(a+i-1,a+n); 17 sum=a[i]+a[i-1]+sum; 18 a[i]=a[i]+a[i-1]; 19 } 20 cout<<sum<<endl; 21 } 22 return 0; 23 }
总结:
本次实验其实挺简单的,主要是要细心。以后每次实验或是做题都要认真写好解题报告,这既是一种学习手段,也复习了实验内容.
浙公网安备 33010602011771号