基本题一基本递归算法.docx
- 文档编号:7951384
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:33
- 大小:134.80KB
基本题一基本递归算法.docx
《基本题一基本递归算法.docx》由会员分享,可在线阅读,更多相关《基本题一基本递归算法.docx(33页珍藏版)》请在冰豆网上搜索。
基本题一基本递归算法
基本题一:
基本递归算法
一、实验目的与要求
1、熟悉C/C++语言的集成开发环境;
2、通过本实验加深对递归过程的理解
二、实验内容:
掌握递归算法的概念和基本思想,分析并掌握“整数划分”问题的递归算法。
三、实验题
任意输入一个整数,输出结果能够用递归方法实现整数的划分。
四、实验步骤
1.理解算法思想和问题要求;
2.编程实现题目要求;
3.上机输入和调试自己所编的程序;
4.验证分析实验结果;
5.整理出实验报告。
五、程序清单
#include
usingnamespacestd;
intq(intn,intm)
{
if((n<1)||(m<1))return0;
if((n==1)||(m==1))return1;
if(n if(n==m)returnq(n,m-1)+1; returnq(n,m-1)+q(n-m,m); } intmain() { inta,b; cout<<"请输入整数a: "; cin>>a; b=q(a,a); cout<<"整数a的划分多少种: "< return0; } 六、实验结果 基本题二: 棋盘覆盖问题 一、实验目的与要求 1、掌握棋盘覆盖问题的算法; 2、初步掌握分治算法 二、实验题: 盘覆盖问题: 在一个2k×2k个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。 在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。 三、实验提示 voidchessBoard(inttr,inttc,intdr,intdc,intsize) { if(size==1)return; intt=tile++, //L型骨牌号 s=size/2; //分割棋盘 //覆盖左上角子棋盘 if(dr //特殊方格在此棋盘中 chessBoard(tr,tc,dr,dc,s); else{//此棋盘中无特殊方格 //用t号L型骨牌覆盖右下角 board[tr+s-1][tc+s-1]=t; //覆盖其余方格 chessBoard(tr,tc,tr+s-1,tc+s-1,s);} //覆盖右上角子棋盘 if(dr //特殊方格在此棋盘中 chessBoard(tr,tc+s,dr,dc,s); else{//此棋盘中无特殊方格 //用t号L型骨牌覆盖左下角 board[tr+s-1][tc+s]=t; //覆盖其余方格 chessBoard(tr,tc+s,tr+s-1,tc+s,s);} //覆盖左下角子棋盘 if(dr>=tr+s&&dc //特殊方格在此棋盘中 chessBoard(tr+s,tc,dr,dc,s); else{//用t号L型骨牌覆盖右上角 board[tr+s][tc+s-1]=t; //覆盖其余方格 chessBoard(tr+s,tc,tr+s,tc+s-1,s);} //覆盖右下角子棋盘 if(dr>=tr+s&&dc>=tc+s) //特殊方格在此棋盘中 chessBoard(tr+s,tc+s,dr,dc,s); else{//用t号L型骨牌覆盖左上角 board[tr+s][tc+s]=t; //覆盖其余方格 chessBoard(tr+s,tc+s,tr+s,tc+s,s);} } 四、程序清单 #include #include usingnamespacestd; inttile=1; intboard[1024][1024]; voidChessBoard(inttr,inttc,intdr,intdc,intsize) { if(size==1)return; intt=tile++,//L型骨牌号 s=size/2;//分割棋盘 //覆盖左上角子棋盘 if(dr //特殊方格在此棋盘中 ChessBoard(tr,tc,dr,dc,s); else{//此棋盘中无特殊方格 //用t号L型骨牌覆盖右下角 board[tr+s-1][tc+s-1]=t; //覆盖其余方格 ChessBoard(tr,tc,tr+s-1,tc+s-1,s);} //覆盖右上角子棋盘 if(dr //特殊方格在此棋盘中 ChessBoard(tr,tc+s,dr,dc,s); else{//此棋盘中无特殊方格 //用t号L型骨牌覆盖左下角 board[tr+s-1][tc+s]=t; //覆盖其余方格 ChessBoard(tr,tc+s,tr+s-1,tc+s,s);} //覆盖左下角子棋盘 if(dr>=tr+s&&dc //特殊方格在此棋盘中 ChessBoard(tr+s,tc,dr,dc,s); else{//用t号L型骨牌覆盖右上角 board[tr+s][tc+s-1]=t; //覆盖其余方格 ChessBoard(tr+s,tc,tr+s,tc+s-1,s);} //覆盖右下角子棋盘 if(dr>=tr+s&&dc>=tc+s) //特殊方格在此棋盘中 ChessBoard(tr+s,tc+s,dr,dc,s); else{//用t号L型骨牌覆盖左上角 board[tr+s][tc+s]=t; //覆盖其余方格 ChessBoard(tr+s,tc+s,tr+s,tc+s,s); } } voidOutBoard(intsize) { inti,j; for(i=0;i { for(j=0;j { cout< cout< } } intmain() { intsize,dr,dc; cout<<"请输入棋盘的规格: "; cin>>size; cout<<"请输入特殊方格所在的行号和列号: "; cin>>dr>>dc; ChessBoard(0,0,dr,dc,size); OutBoard(size); cout<<"一共有"< return0; } 五、实验结果 提高题一: 二分搜索 一、实验目的与要求 1、熟悉二分搜索算法; 2、初步掌握分治算法; 二、实验题 1、设a[0: n-1]是一个已排好序的数组。 请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置I和大于x的最大元素位置j。 当搜索元素在数组中时,I和j相同,均为x在数组中的位置。 2、设有n个不同的整数排好序后存放于t[0: n-1]中,若存在一个下标I,0≤i<n,使得t[i]=i,设计一个有效的算法找到这个下标。 要求算法在最坏的情况下的计算时间为O(logn)。 三、实验提示 1、用I,j做参数,且采用传递引用或指针的形式带回值。 boolBinarySearch(inta[],intn,intx,int&i,int&j) { intleft=0; intright=n-1; while(left { intmid=(left+right)/2; if(x==a[mid]) { i=j=mid; returntrue; } if(x>a[mid]) left=mid+1; else right=mid-1; } i=right; j=left; returnfalse; } intSearchTag(inta[],intn,intx) { intleft=0; intright=n-1; while(left { intmid=(left+right)/2; if(x==a[mid])returnmid; if(x>a[mid]) right=mid-1; else left=mid+1; } return-1; } 四、程序清单 (1)#include usingnamespacestd; intb[80],n; boolBinarySearch(inta[],intn,intx); intmain() { cout<<"请问输入多少个元素? "; cin>>n; cout<<"请输入已排好序的元素集合: "; for(intk=0;k cin>>b[k]; inty; cout<<"请输入要查找的元素: "; cin>>y; BinarySearch(b,n,y); return0; } boolBinarySearch(inta[],intn,intx) { inti,j; intleft=0; intright=n-1; while(left<=right) { intmid=(left+right)/2; if(x==a[mid]) { i=j=mid; cout<<"你查找的元素序号为: "< returntrue; } if(x>a[mid]) left=mid+1; else right=mid-1; } i=right; j=left; cout<<"你查找的元素不存在,小于它的最大元素和大于它的最小元素分别为: "< returnfalse; } 五、实验结果 (1) 实验二动态规划算法(4学时) 基本题一: 最长公共子序列问题 一、实验目的与要求 1、熟悉最长公共子序列问题的算法; 2、初步掌握动态规划算法; 二、实验题 若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有: zj=xij。 例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。 给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。 给定2个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最长公共子序列。 三、实验提示 include"stdlib.h" #include"string.h" voidLCSLength(char*x,char*y,intm,intn,int**c,int**b) { inti,j; for(i=1;i<=m;i++)c[i][0]=0; for(i=1;i<=n;i++)c[0][i]=0; for(i=1;i<=m;i++) for(j=1;j<=n;j++) { if(x[i]==y[j]) { c[i][j]=c[i-1][j-1]+1; b[i][j]=1; } elseif(c[i-1][j]>=c[i][j-1]) { c[i][j]=c[i-1][j]; b[i][j]=2; } else { c[i][j]=c[i][j-1]; b[i][j]=3; } } } voidLCS(inti,intj,char*x,int**b) { if(i==0||j==0)return; if(b[i][j]==1) { LCS(i-1,j-1,x,b); printf("%c",x[i]); } elseif(b[i][j]==2) LCS(i-1,j,x,b); elseLCS(i,j-1,x,b); } 四程序清单 #include #include #include usingnamespacestd; #defineN20 voidLCSLength(charx[N+1],chary[N+1],intm,intn,intc[N+1][N+1],intb[N+1][N+1]) { inti,j; for(i=1;i<=m;i++)c[i][0]=0; for(i=1;i<=n;i++)c[0][i]=0; for(i=1;i<=m;i++) { for(j=1;j<=n;j++) { if(x[i]==y[j]) { c[i][j]=c[i-1][j-1]+1; b[i][j]=1; } elseif(c[i-1][j]>=c[i][j-1]) { c[i][j]=c[i-1][j]; b[i][j]=2; } else {c[i][j]=c[i][j-1]; b[i][j]=3; } } } for(ints=1;s<=m;s++) { for(intt=1;t<=n;t++) { cout< }cout< } cout<<"最长公共子序列长度: "< } voidLCS(inti,intj,charx[N+1],intb[N+1][N+1]) { if(i==0||j==0)return; if(b[i][j]==1) { LCS(i-1,j-1,x,b); cout< } elseif(b[i][j]==2) { LCS(i-1,j,x,b); } else { LCS(i,j-1,x,b); } } intmain() { charx[N+1],y[N+1]; intm,n; intb[N+1][N+1]; intc[N+1][N+1]; cout<<"请输入第一个序列: "< cin>>x+1; cout<<"请输入第二个序列: "< cin>>y+1; m=strlen(x+1); n=strlen(y+1); cout<<"矩阵为: "< LCSLength(x,y,m,n,c,b); cout<<"最长公共子序列为: "< LCS(m,n,x,b); cout< return0; } 五、实验结果 基本题二: 最大字段和问题 一、实验目的与要求 1、熟悉最长最大字段和问题的算法; 2、进一步掌握动态规划算法; 二、实验题 若给定n个整数组成的序列a1,a2,a3,……an,求该序列形如ai+ai+1+……+an的最大值。 三、实验提示 intMaxSum(intn,int*a,int&besti,int&bestj) { intsum=0; for(inti=1;i<=n;i++) for(intj=i;j<=n;j++) { intthissum=0; for(intK=i;k<=j;k++)thissum+=a[k]; if(thissum>sum) { sum=thissum; besti=i; bestj=j; } } returnsum; } intMaxSum(intn,int*a,int&besti,int&bestj) { intsum=0; for(inti=1;i<=n;i++) { intthissum=0; for(intj=i;j<=n;j++) { thissum+=a[j]; if(thissum>sum) { sum=thissum; besti=i; bestj=j; } } } returnsum; } 四、程序清单 #include #include #include usingnamespacestd; intmain() { intMaxSum(intn,int*a,int&besti,int&bestj); int*a=newint[50]; intx,n,besti,bestj; cout<<"请输入序列的个数: "; cin>>n; cout<<"请输入整数序列: "; for(inti=0;i { cin>>a[i]; } x=MaxSum(n,a,besti,bestj); cout<<"最大字段和: "<<"起始位置: "< "< "< return0; } intMaxSum(intn,int*a,int&besti,int&bestj) { intsum=0; for(inti=1;i<=n;i++) { intthissum=0; for(intj=i;j<=n;j++) { thissum+=a[j]; if(thissum>sum) { sum=thissum; besti=i; bestj=j; } } } returnsum; } 五、实验结果 实验三贪心算法(2学时) 基本题一: 多机调度问题 一、实验目的与要求 1、熟悉多机调度问题的算法; 2、初步掌握贪心算法; 二、实验题 要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。 约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。 作业不能拆分成更小的子作业。 三、实验提示 1、把作业按加工所用的时间从大到小排序 2、如果作业数目比机器的数目少或相等,则直接把作业分配下去 3、 如果作业数目比机器的数目多,则每台机器上先分配一个作业,如下的作业分配时,是选那个表头上s最小的链表加入新作业。 typedefstructJob { intID;//作业号 inttime;//作业所花费的时间 }Job; typedefstructJobNode//作业链表的节点 { intID; inttime; JobNode*next; }JobNode,*pJobNode; typedefstructHeader //链表的表头 { ints; pJobNodenext; }Header,pHeader; intSelectMin(Header*M,intm) { intk=0; for(inti=1;i { if(M[i].s } returnk; 四、程序清单 #include #defineN 如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。 copyright@ 2008-2022 冰点文档网站版权所有 经营许可证编号:鄂ICP备2022015515号-1=tc+s) =tc+s)
冰豆网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。