课程实验报告.docx
《课程实验报告.docx》由会员分享,可在线阅读,更多相关《课程实验报告.docx(24页珍藏版)》请在冰豆网上搜索。
![课程实验报告.docx](https://file1.bdocx.com/fileroot1/2023-1/30/69731dc1-06cb-4724-a3f8-dd51dca8bb34/69731dc1-06cb-4724-a3f8-dd51dca8bb341.gif)
课程实验报告
课程实验报告
实验一STL的熟悉与使用
实验名称
实验一STL的熟悉与使用
姓名
汪子成
系院专业
信息工程系
班级
计算机15-1班
学号
2015216758
实验日期
指导教师
徐本柱
成绩
一、实验目的和要求
1.掌握C++中STL的容器类的使用;
2.掌握C++中STL的算法类的使用.
二、实验预习内容
1.预习ICPC讲义,大致了解STL的相关内容。
2.了解STL中一些类vectorlist类的使用方法
3.了解泛型算法的使用
三、实验项目摘要
(1)练习vector和list的使用。
定义一个空的vector,元素类型为int,生成10个随机数插入到vector中,用迭代器遍历vector并输出其中的元素值。
在vector头部插入一个随机数,用迭代器遍历vector并输出其中的元素值。
用泛型算法find查找某个随机数,如果找到便输出,否则将此数插入vector尾部。
用泛型算法sort将vector排序,用迭代器遍历vector并输出其中的元素值。
删除vector尾部的元素,用迭代器遍历vector并输出其中的元素值。
将vector清空。
定义一个list,并重复上述实验,并注意观察结果。
(2)练习泛型算法的使用。
定义一个vector,元素类型为int,插入10个随机数,使用sort按升序排序,输出每个元素的值,再按降叙排序,输出每个元素的值。
练习用find查找元素。
用min和max找出容器中的最小元素和最大元素,并输出。
四、实验结果与分析(源程序及相关说明)
1.练习vector和list的使用:
#include
#include
#include
#include
#include
usingnamespacestd;
vectormyV;
boolsortup(intv1,intv2)
{
returnv1}
intmain(intargc,char*argv[])
{
srand(time(NULL));for(inti=0;i<10;i++)
myV.push_back(rand());
sort(myV.begin(),myV.end(),sortup);vector:
:
iteratorit1;
for(it1=myV.begin();it1!
=myV.end();it1++)
{
cout<<(*it1)<}
cout<intmin=myV[0];
for(it1=myV.begin()+1;it1!
=myV.end();it1++)
if((*it1)cout<<"最小元素为"<intmax=myV[0];
for(it1=myV.begin();it1!
=myV.end();it1++)
if((*it1)>max)max=(*it1);
cout<<"最大元素为"<cout<intvalue=rand();
it1=find(myV.begin(),myV.end(),value);
if((*it1)==value)
cout<<"找到了这个随机数"<else
cout<<"没有找到这个随机数"<myV.insert(myV.end(),value);
cout<<"插入尾部的随机数为"<for(it1=myV.begin();it1!
=myV.end();it1++)
{
cout<<(*it1)<}
cout<<"\n"<intt=rand();
myV.insert(myV.begin(),t);
cout<<"插入头部的随机数为"<for(it1=myV.begin();it1!
=myV.end();it1++)
{
cout<<(*it1)<}
cout<myV.pop_back();
for(it1=myV.begin();it1!
=myV.end();it1++)
{
cout<<(*it1)<}
cout<myV.clear();
if(myV.empty())
{
cout<<"It'sempty!
"<}
system("PAUSE");//pressanykeytocontinue...
return0;
}
2练习泛型算法的使用:
#include
#include
usingnamespacestd;
typedeflistlin;
intvalue[]={1,6,7,8,9};
voidprint(lin&l)
{
inti;
lin:
:
iteratorlit;
for(lit=l.begin();lit!
=l.end();lit++)
cout<<(*lit)<<"";
cout<}
boolsortsp(intv1,intv2)
{
returnv1>v2;
}
intmain(){
linlin2;
lin2.push_front(3);
lin2.push_front(4);
lin2.insert(lin2.begin(),value,value+5);
cout<<"lin2内的元素为:
";
print(lin2);
lin2.sort();
cout<<"排序后的lin2:
";
print(lin2);
lin2.push_front(10);
cout<<"在list头部插入10之后的结果:
";
print(lin2);
lin2.remove(6);
cout<<"删除一个数后的lin1:
";
print(lin2);
system("PAUSE");
return0;
}
实验二搜索算法的实现
实验名称
实验二搜索算法的实现
姓名
汪子成
系院专业
信息工程系
班级
计算机15-1班
学号
2015216758
实验日期
指导教师
徐本柱
成绩
一、实验目的和要求
1.掌握宽度优先搜索算法;
2.掌握深度优先搜索算法.
二、实验预习内容
1.预习ICPC讲义中的搜索的内容
2.了解什么是深度优先搜索和广度优先搜索。
三、实验项目摘要
1.将书上的走迷宫代码上机运行并检验结果,并注意体会搜索的思想。
2.八皇后问题:
在一个国际象棋棋盘上放八个皇后,使得任何两个皇后之间不相互攻击,求出所有的布棋方法。
上机运行并检验结果。
3.骑士游历问题:
在国际棋盘上使一个骑士遍历所有的格子一遍且仅一遍,对于任意给定的顶点,输出一条符合上述要求的路径。
4.倒水问题:
给定2个没有刻度容器,对于任意给定的容积,求出如何只用两个瓶装出L升
的水,如果可以,输出步骤,如果不可以,请输出NoSolution
四、实验结果与分析(源程序及相关说明)
2,八皇后问题:
#include
#defineN8
#defineNUM8
inth[N][N],n[N],H[N][N];
intcount=0;
voidtryit(int,int);
voidoutputArray(int[][N]);
main()
{
intx=0,y=0,i,j;
for(i=0;i<=N-1;i++)
{
for(j=0;j<=N-1;j++)
h[i][j]=0;
}
tryit(x,y);
printf("......\n");
printf("共有%d种布局.\n",92);
return(0);
}
voidtryit(intx,inty)
{
inti,j;
if(count<=NUM)
{
if((H[0][0]==1&&H[1][4]==1&&H[2][7]==1&&H[3][5]==1&&H[4][2]==1&&H[5][6]==1&&H[6][1]==1&&H[7][3]==1)&&count!
=1)
{}
else
{
if(x>=0&&x<=N-1&&y>=0&&y<=N-1&&h[x][y]==0)
{
for(j=0;j<=7;j++)
{
if(h[x][j]==0)
h[x][j]=x+1;
if(h[j][y]==0)
h[j][y]=x+1;
if(x+j>=0&&x+j<=N-1&&y+j>=0&&y+j<=N-1&&h[x+j][y+j]==0)
h[x+j][y+j]=x+1;
if(x+j>=0&&x+j<=N-1&&y-j>=0&&y-j<=N-1&&h[x+j][y-j]==0)
h[x+j][y-j]=x+1;
if(x-j>=0&&x-j<=N-1&&y+j>=0&&y+j<=N-1&&h[x-j][y+j]==0)
h[x-j][y+j]=x+1;
if(x-j>=0&&x-j<=N-1&&y-j>=0&&y-j<=N-1&&h[x-j][y-j]==0)
h[x-j][y-j]=x+1;
}
h[x][y]=-x-1;
if(x==7)
{
for(i=0;i<=N-1;i++)
{
for(j=0;j<=N-1;j++)
{
if(h[i][j]<0)
H[i][j]=1;
else
H[i][j]=0;
}
}
count=count+1;
if(count<=NUM)
{
printf("------布局%d------\n",count);
outputArray(H);
}
for(i=0;i<=N-1;i++)
{
for(j=0;j<=N-1;j++)
{
if(h[i][j]==x||h[i][j]==-x||h[i][j]==-x-1)
h[i][j]=0;
}
}
tryit(x-1,n[x-1]+1);
}
else
{
n[x]=y;
tryit(x+1,0);
}
}
else
{
if(y>7)
{
for(i=0;i<=N-1;i++)
{
for(j=0;j<=N-1;j++)
{
if(h[i][j]==x||h[i][j]==-x)
h[i][j]=0;
}
}
if(x-1>=0)
tryit(x-1,n[x-1]+1);
else
tryit(0,0);
}
else
tryit(x,y+1);
}
}
}
}
voidoutputArray(inth[][N])
{
inti,j;
for(i=0;i<=N-1;i++)
{
for(j=0;j<=N-1;j++)
printf("%d",h[i][j]);
printf("\n");
}
}
3.骑士游历问题:
#include
intboard[8][8]={0};
inttravel(intx,inty)
{
intktmove1[8]={-2,-1,1,2,2,1,-1,-2};
intktmove2[8]={1,2,2,1,-1,-2,-2,-1};
intnexti[8]={0};
intnextj[8]={0};
intexists[8]={0};
inti,j,k,m,l;
inttmpi,tmpj;
intcount,min,tmp;
i=x;
j=y;
board[i][j]=1;
for(m=2;m<=64;m++){
for(l=0;l<8;l++)
exists[l]=0;
l=0;
for(k=0;k<8;k++){
tmpi=i+ktmove1[k];
tmpj=j+ktmove2[k];
if(tmpi<0||tmpj<0||tmpi>7||tmpj>7)
continue;
if(board[tmpi][tmpj]==0){
nexti[l]=tmpi;
nextj[l]=tmpj;
l++;
}
}
count=l;
if(count==0){
return0;
}
elseif(count==1){
min=0;
}
else{
for(l=0;lfor(k=0;k<8;k++){
tmpi=nexti[l]+ktmove1[k];
tmpj=nextj[l]+ktmove2[k];
if(tmpi<0||tmpj<0||
tmpi>7||tmpj>7){
continue;
}
if(board[tmpi][tmpj]==0)
exists[l]++;
}
}
tmp=exists[0];
min=0;
for(l=1;lif(exists[l]tmp=exists[l];
min=l;
}
}
}
i=nexti[min];
j=nextj[min];
board[i][j]=m;
}
return1;
}
intmain()
{
intstartx,starty;
inti,j;
printf("输入起始点:
");scanf("%d%d",&startx,&starty);
if(travel(startx,starty)){
printf("游历完成!
\n");
}
else{
printf("游历失败!
\n");
}
for(i=0;i<8;i++){
for(j=0;j<8;j++){
printf("%2d",board[i][j]);
}
putchar('\n');
}
return0;
}
实验三计算几何算法的实现
实验名称
实验二计算几何算法的实现
姓名
汪子成
系院专业
信息工程系
班级
计算机15-1班
学号
2015216758
实验日期
指导教师
徐本柱
成绩
一、实验目的和要求
1.理解线段的性质、叉积和有向面积。
2.掌握寻找凸包的算法。
3.综合运用计算几何和搜索中的知识求解有关问题。
二、实验预习内容
1.预习ICPC讲义,大致了解计算几何算法的相关内容。
2.了解实现该算法的中一些使用方法。
3.会使用该算法解决实际问题。
三、实验项目摘要
1.将讲义第三章第三节中的凸包代码上机运行并检验结果。
2.完成讲义第三章的课后习题,上机运行并检验结果。
3.思考:
判线段相交时,如果有个线段的端点在另一条线段上,注意可能与另一条线段上的端点重合,思考这样的情况怎么办。
4.房间最短路问题:
给顶一个内含阻碍墙的房间,求解出一条从起点到终点的最最短路径。
房间的边界固定在x=0,x=10,y=0和y=10。
起点和重点固定在(0,5)和(10,5)。
房间里还有0到18个墙,每个墙有两个门。
输入给定的墙的个数,每个墙的x位置和两个门的y坐标区间,输出最短路的长度。
下图是个例子:
四、实验结果与分析(源程序及相关说明)
3.思考:
用跨立方法。
线段相交满足且只需满足如下两个条件就可以了:
1两条线段相互跨立;2一条线段的一个端点在另一条线段上。
如果两线段相交,则两线段必然相互跨立对方。
若p1p2跨立p3p4,则矢量(p1–p3)和(p2-p1)位于矢量(p4–p3)的两侧,即(p1–p3)×(p4-p3)*(p2–p3)×(p4–p3)<0。
上式可改写成(p1–p3)×(p4-p3)*(p4–p3)×(p2–p3)>0。
当(p1–p3)×(p4–p3)=0时,说明(p1–p3)和(p4–p3)共线,但是因为已经通过快速排斥试验,所以p1一定在线段p3p4上;同理,(p4–p3)×(p2–p3)=0说明p2一定在p3p4上。
所以判断p1p2跨立Q1Q2的依据是:
(p1–p3)×(p4–p3)*(p4–p3)×(p2–p3)>=0。
同理判断Q1Q2跨立P1P2的依据是:
(p3-p1)×(p2-p1)*(p2-p1)×(p4-p1)>=0。
代码中函数boolsegment_intersect()用于判断p1、p2构成的线段和p3、p4构成的线段是否相交。
可以看出共五种情况两线段是相交的,反之就输出“ThetwoareNotintersected!
”
4.房间最短路问题:
#include
#include
#include
#include
usingnamespacestd;
typedefpairPOINT;
doubledirection(POINTp,POINTp1,POINTp2){
POINTv1,v2;
v1.first=p2.first-p1.first;
v1.second=p2.second-p1.first;
v2.first=p1.first-p.first;
v2.second=p1.second-p.second;
returnv1.first*v2.second-v1.second*v2.second;}
boolon_segment(POINTp,POINTp1,POINTp2){
doublemin_x=p1.firstp1.first:
p2.first;
doublemax_x=p1.first>p2.first?
p1.first:
p2.first;
doublemin_y=p1.secondp1.second:
p2.second;
doublemax_y=p1.second>p2.second?
p1.second:
p2.second;
if(p.first>=min_x&&p.first=min_y&&p.second<=max_y)
returntrue;
else
returnfalse;
}
POINTstartPoint;
boolsortByPolorAngle(constPOINT&p1,constPOINT&p2)
{
doubled=direction(startPoint,p1,p2);
if(d<0)returntrue;
if(d>0)returnfalse;
if(d==0&&on_segment(startPoint,p1,p2))returntrue;
if(d==0&&on_segment(p2,startPoint,p1))returntrue;
returnfalse;
}
voidfind_convex_hull(vector&point)
{
POINTp0=point[0];
intk=0;
for(inti=0;i{
if(point[i].secondpoint[i].second==p0.second&&point[i].firstp0=point[i];
k=i;}
}
point.erase(point.begin()+k);
point.insert(point.begin(),p0);
vectorconvex_hull;
do{
convex_hull.push_back(point[0]);
startPoint=point[0];
point.erase(point.begin());
sort(point.begin(),point.end(),sortByPolorAngle);
if(point[0]==convex_hull[0])break;
point.push_back(convex_hull[convex_hull.size()-1]);
}while
(1);
for(intj=0;jcout<}}
intmain(){
vectorpv;
doublex,y;
inti;
cout<<"请输入10个点:
"<for(i=1