算法实验一实验报告文档格式.docx
《算法实验一实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《算法实验一实验报告文档格式.docx(25页珍藏版)》请在冰豆网上搜索。
//正整数或者最大加数=1时,只有一种划分情况
if(n<
m)returnq(n,n);
//最大加数实际不能大于正整数本身
if(n==m)returnq(n,m-1)+1;
//递归,n的划分由其q(n,m-1)和n1=n组成
returnq(n,m-1)+q(n-m,m);
//正整数n的最大加数n1不大于m的划分由n1=m的划分和n1=m-1的划分组成
}
voidmain()
intn,m;
cout<
<
"
请输入一个整数n(-1退出):
endl;
cin>
>
n;
while(n>
=1)
{
cout<
请输入一个最大加数m:
cin>
m;
正整数n的最大加数m的划分数为"
q(n,m)<
}
进行编译如下:
运行结果如下:
四、实验步骤
1.理解算法思想和问题要求;
2.编程实现题目要求;
3.上机输入和调试自己所编的程序;
4.验证分析实验结果;
5.整理出实验报告。
基本题二:
棋盘覆盖问题
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<
tr+s&
&
dc<
tc+s)
//特殊方格在此棋盘中
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);
//覆盖右上角子棋盘
dc>
=tc+s)
chessBoard(tr,tc+s,dr,dc,s);
//用t号L型骨牌覆盖左下角
board[tr+s-1][tc+s]=t;
chessBoard(tr,tc+s,tr+s-1,tc+s,s);
//覆盖左下角子棋盘
if(dr>
=tr+s&
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);
//覆盖右下角子棋盘
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<
intboard[65][65],tile;
/*tile为纸片编号*/
intt=tile++,//L型骨牌号
board[tr+s-1][tc+s]=t;
//输出最终的结果
voidresult(intb[][65],intn){
inti,j;
for(i=1;
i<
=n;
i++)
{
for(j=1;
j<
j++)
b[i][j]<
"
;
}
}
intmain(){
intsize,dr,dc;
选择输入4种不同形态的L型骨牌中的一种(4/8/16/64):
size;
请输入特殊的块的位置(x,y):
dr>
dc;
结果如下:
board[dr][dc]=-1;
tile++;
chessBoard(1,1,dr,dc,size);
result(board,size);
}
运行调试结果如下:
试运行结果如下:
提高题一:
二分搜索
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<
right)
intmid=(left+right)/2;
if(x==a[mid])
i=j=mid;
returntrue;
if(x>
a[mid])
left=mid+1;
else
right=mid-1;
2
i=right;
j=left;
returnfalse;
intSearchTag(inta[],intn,intx)
if(x==a[mid])returnmid;
return-1;
实验题1代码编写如下:
voidBubbleSort(int*pData,intCount)
//冒泡排序的函数,pData中从0位置处存了Count个数,该函数将数组中元素排序
{
intiTemp;
for(inti=1;
Count;
i++)
for(intj=Count-1;
j>
=i;
j--)
if(pData[j]<
pData[j-1])
iTemp=pData[j-1];
pData[j-1]=pData[j];
pData[j]=iTemp;
j)
//数组a大小为n,数组中存放了已经排好序(升序)的数列
intmid=0;
right)
mid=(left+right)/2;
if(x==a[mid])
a[mid])
else
intSearchTag(inta[],intn,intx)
returnmid;
return-1;
intmain()
inta[100];
请输入数组中数的个数,小于100:
intnum=0;
num;
请输入数组中的数:
for(inti=0;
a[i];
//下面将数组a排成升序
BubbleSort(a,num);
下面输出排序后的数组:
for(i=0;
printf("
%4d"
a[i]);
请输入要查找的数:
intx=0;
x;
intj=0;
if(BinarySearch(a,num,x,i,j))
找到了,位置为"
没找到,小于该数的最大元素位置为"
大于该数的最小元素的位置为"
(第一个元素的位置为0)"
return0;
试运行调试结果如下:
运行结果如下图所示:
实验题2编写代码如下:
/*根据题目中的隐含要求,现在将问题进行简化,假设数组中存放的数全部为整数*/
//冒泡排序的函数,pData中从0位置处存了Count个数,该函数将数组中元素排升序
boolBinaryFind_iei(inta[],intn,int&
i)
if(mid==a[mid])
i=mid;
//找到了
if(mid>
left=mid;
right=mid;
for(intii=0;
ii<
ii++)
a[ii];
if(BinaryFind_iei(a,num,j))
不存在符合第i个位置等于i的元素。
return0;
运行结果如下:
结果分析:
利用分治策略求解时,所需时间取决于分解后子问题的个数、子问题的规模大小等素,而二分法,由于其划分的简单和均匀的特点,是经常采用的一种有效的方法,例如二分法检索。
提高题二:
用分治法实现元素选择
一、实验要求与目的
1、了解分治法的基本思想,掌握递归程序编写方法;
2、使用分治法编程,求解线形序列中第k小元素。
二、实验内容
1、给定线形序列集中n个元素和一个整数k,1≤k≤n,输出这n个元素中第k小元素的值及其位置。
2、简述该算法的原理、步骤。
对该算法与直接排序查找进行比较。
3、编写并调试程序。
测试要求:
元素个数不少于100;
分三种情况:
k=1、k=n和k=中位数。
编写程序代码如下所示:
stdlib.h>
time.h>
stdio.h>
malloc.h>
intpartition(inta[],intp,intr)
intz=p,x=r+1;
inty=a[p];
intt;
while
(1)
while(a[++z]<
y&
z<
r);
//空循环,不符合条件时向下执行
while(a[--x]>
y);
if(z>
=x)break;
t=a[z];
a[z]=a[x];
a[x]=t;
a[p]=a[x];
a[x]=y;
returnx;
voidquicksort(inta[],intp,intr)
intq;
if(p<
r)
q=partition(a,p,r);
quicksort(a,p,q-1);
quicksort(a,q+1,r);
intmain()
for(;
)
intk,*a,*b,n,i,d,s;
请输入数组个数:
);
scanf("
%d"
&
n);
\n"
a=(int*)malloc(sizeof(int)*n);
//给数组a分配空间
srand((unsigned)time(NULL));
b=(int*)malloc(sizeof(int)*n);
//给数组b分配空间
for(i=0;
a[i]=rand()%100+1;
//产生小于100的数据
%d\t"
if((i+1)%10==0)//每行10个数据
for(i=0,d=0;
d<
d++)//将数组a的值赋给数组b
b[d]=a[i];
i++;
quicksort(a,0,i-1);
//调用快速排序进行排序
排序后"
if((i+1)%10==0)//输出排好序的数组a,每行10个数据
请输入第k小元素:
k);
for(d=0;
d++)
if(b[d]==a[k-1])//从数组b中找出第k小的数在原数组中的位置
s=d+1;
第%d小元素为:
k,a[k-1]);
第%d小元素位置为:
k,s);
system("
pause"
试运行调试结果如下:
测试一:
K=1
测试二:
K=n(此处为K=n=102)
测试三:
k=中位数
五:
实验总结
通过此次实验进一步熟悉了C/C++语言的集成开发环境以及进一步加深了对递归过程的理解,理论结合实际让自己对此阶段的知识掌握的更加牢固,收益颇丰。