测试卷1.0
1. 旧事重提
二分法实现幂函数x的n次方pow(x,n)
这里的二分法是指减少乘法的次数,把重复的运算省去。我要求x的n次方,那么先求x的n/2次方,然后两个相乘起来。如此递归下去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| int pow(int x,int n){ int t=1; while(n){ if(n%2==1){ n=n-1; t*=x; } x*=x; n/=2; } return t; }
double fun(double x,int n){ if(n==0) return 1; double half; if(n%2==1){ half=fun(x,n/2); return x*half*half; }else{ half=fun(x,n/2); return half*half; } } double pow(double x,int n){ double result=fun(x,n); if(n<0) result=1/result; return result; }
|
2. 有两个n维向量相乘,求其点乘的最小值
两个n维的向量,相乘的点是指将向量对应维度的乘积相加,但是我们可以将向量维度交换下可以得到更小的向量点乘,例如3维向量:1,3,-5和4,-2,-1最小向量点乘为-27,即将维度变为:3,1,-5和-2,-1,4。只需要把第一个向量进行全排列,就可以得到所有的乘积
程序设计要求:输入一个整数n为向量的维度,然后输入两个n维度的向量,用空格区别向量元素,输出为一行,包含一个整数,为最小的点乘。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
#include<iostream> using namespace std; const int Maxnn=1e9+1; const int Maxn=1e2+1; int n; int a[Maxn],b[Maxn]; int sum; void backtrack(int t){ if(t>n){ sum=0; for(int i=1;i<=n;i++) sum+=a[i]*b[i]; if(sum<ans) ans=sum; }else{ for(int i=t;i<=n;i++) { swap(a[t],a[i]); backtrack(t+1); swap(a[t],a[i]); } } } int main(){ cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) cin>>b[i]; backtrack(1); cout<<ans<<endl; return 0; }
|
3. 二叉排序树删除某个结点。要求用非递归算法并释放掉该结点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
void Delete(BiTree *p){ BiTree *q,*s; if(p->rchild==NULL) { p=p->lchild; if(p==NULL) delete p; }else if(p->lchild==NULL){ p=p->rchild; }else{ q=p; s=p->lchild; while(s->rchild){ q=s; s=s->rchild; } p->data=s->data; if(q!=p) { q->rchild=s->lchild; }else{ q->lchild=s->lchild; } } }
|
4. 用回溯法来解决装载问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include<iostream> using namespace std; const int Maxn=1e3+7; int c; int n; int w[Maxn]; int r; int x[Maxn]; int cw; int bestw; int bestx[Maxn]; void backtrack(int t){ if(t>n){ if(cw>bestw){ bestw=cw; for(int i=1;i<=n;i++) bestx[i]=x[i]; } return; } r-=w[t]; if(vw+w[t]<=c){ cw+=w[t]; x[t]=1; backtrack(t+1); cw-=w[t]; } if(r+cw>bestw) { x[t]=0; backtrack(t+1); } r+=w[t]; } int main(){ cin>>n; for(int i=1;i<=n;i++) cin>>w[i]; for(int i=1;i<=n;i++) r+=w[i]; backtrack(1); for(int i=0;i<=n;i++) cout<<bestx[i]<<"\t"; cout<<endl; return 0; }
|
5. 二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和。给定一棵二叉树T,才用二叉链表存储,结点结构为:left weight right,其中叶结点的weight域保存该结点的非负权值。设root为指向T的根节点的指针,请设计求T的WPL的算法。要求:
- 给出算法的基本设计思想
- 使用C或C++语言,给出二叉树结点的数据类型定义
- 根据设计思想,采用C或C++语言描述算法,关键之处给出注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
struct BTree{ int weight; BTree *left,*right; }; int WPL(BTree *root) { return WPL1(root,0); } int WPL1(BTree *root,int d) { if(root->left==NULL&&root->right==NULL) return root->weight*d; else return WPL1(root->left,d+1)+WPL1(root->right,d+1); }
|
6. 二路插入排序是将待排关键字序列r[1…n]中关键字分二路分别按序列插入到辅助向量d[1..n]前半部和后半部,其原则为,先将r[1]赋为d[1],再从r[2]记录开始分二路插入。编写实现二路插入排序算法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#include <iostream> using namespace std; const int Maxn=1e3+2; int r[Maxn],d[Maxn]; int n; void fun() { d[1]=r[1]; int first=1,final=1; for(int i=2;i<=n;i++) if(r[i]>d[1]) { low=1; high=final; while(low<=high) { m=(low+high)/2; if(r[i]<d[m]) high=m-1; else low=m+1; } for(j=final;j>=high+1;j--) d[j+1]=d[j]; d[high+1]=r[i]; final++; } else { if(first==1) { first=n; d[n]=r[i]; } else { low=frst; high=n; while(low<=high) { m=(low+high)/2; if(r[i]<d[m]) high=m-1; else low=m+1; } for(int j=first;j<=high;j++) d[j-1]=d[j]; d[high]=r[i];first--; } } r[1]=d[first]; for(i=first%n+1,j=2;i!=first;i=i%n+1,j++) r[j]=d[i]; } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>r[i]; fun(); for(int i=1;i<=n;i++) cout<<r[i]<<" "; return 0; }
|
7. 钱币找零问题
指定币值和相应数量,用最少的数量凑齐某金额
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <iostream> #include <stdio.h>
using namespace std; const int maxn=1e4+5; int dp[100][maxn]; int coin[maxn],num[maxn];
int main(){ int m,n; cin>>n>>m; for(int i=1;i<=m;i++) cin>>coin[i]; for(int i=1;i<=m;i++) cin>>num[i]; for(int i=0;i<100;i++){ for(int j=1;j<maxn;j++) dp[i][j]=1e9; dp[i][0]=0; } for(int i=1;i<=m;i++){ for(int j=1;j<=num[i];j++){ for(int k=1;k<=n;k++){ if(k>=coin[i]*j) dp[i][k]=min(dp[i][k],dp[i-1][k-coin[i]*j]+j); else dp[i][k]=min(dp[i][k], dp[i-1][k]); } } } int ans=1e9; for(int i=1;i<=m;i++) ans=min(ans,dp[i][n]); cout<<ans<<endl; return 0; }
|