ImageVerifierCode 换一换
格式:DOCX , 页数:64 ,大小:34.85KB ,
资源ID:9737131      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9737131.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(ACM程序设计竞赛例题1.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

ACM程序设计竞赛例题1.docx

1、ACM程序设计竞赛例题1备战ACM资料习题1 0-1背包问题在0 / 1背包问题中,需对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高。 程序如下:#include void readdata();void search(int);void checkmax();void printresult();int c=35, n=10; /c: 背包容量;n:物品数int w10, v10; /wi、vi:第i件物品的重量和价值int a10, max;

2、/a数组存放当前解各物品选取情况;max:记录最大价值 /ai=0表示不选第i件物品,ai=1表示选第i件物品int main() readdata(); /读入数据 search(0); /递归搜索 printresult();void search(int m) if(m=n) checkmax(); /检查当前解是否是可行解,若是则把它的价值与max比较 else am=0; /不选第m件物品 search(m+1); /递归搜索下一件物品 am=1; /不选第m件物品 search(m+1); /递归搜索下一件物品 void checkmax() int i, weight=0, va

3、lue=0; for(i=0;in;i+) if(ai=1) /如果选取了该物品 weight = weight + wi; /累加重量 value = value + vi; /累加价值 if(weightmax) /且价值大于max max=value; /替换maxvoid readdata() int i; for(i=0;in;i+) scanf(%d%d,&wi,&vi); /读入第i件物品重量和价值void printresult() printf(%d,max);2 装载问题有两艘船,载重量分别是c1、 c2,n个集装箱,重量是wi (i=1n),且所有集装箱的总重量不超过c1

4、+c2。确定是否有可能将所有集装箱全部装入两艘船。提示:求出不超过c1的最大值max,若总重量max =n*n) checkmax(); /检查当前解是否是可行解,若是则把它的价值与max比较 else search(m+1); /该位置不放堡垒递归搜索下一个位置 if(canplace(m) /判断第m个格子是否能放堡垒 place(m); /在第m个格子上放置一个堡垒 search(m+1); /递归搜索下一个位置 takeout(m); /去掉第m个格子上放置的堡垒 5 8皇后问题在一个的棋盘里放置个皇后,要求这8个皇后两两之间互相都不“冲突”。#include #include voi

5、d search(int);void printresult(); /打印结果int canplace(int,int); /判断该位置能否放置皇后void place(int,int); /在该位置能否放置皇后void takeout(int,int); /把该位置放置皇后去掉int a8; /ai存放第i个皇后的位置int main() search(0); /递归搜索void search(int m) int i; if(m=8) /当已经找出一组解时 printresult(); /输出当前结果 else for(i=0;i8;i+) /对当前行0到7列的每一个位置 if(canpl

6、ace(m,i) /判断第m个格子是否能放堡垒 place(m,i); /在(m,i)格子上放置一个皇后 search(m+1); /递归搜索下一行 takeout(m,i); /把(m,i)格子上的皇后去掉 int canplace(int row, int col) int i; for(i=0;irow;i+) if(abs(i-row)=abs(ai-col)|ai=col) return(0); return(1);void place(int row, int col) arow=col;void takeout(int row, int col) arow=-1;void pri

7、ntresult() int i,j; for(i=0;i8;i+) for(j=0;j8;j+) if(ai=j) printf( A ); else printf( . ); printf(n); printf(n);6 素数环问题把从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数。分析:用回溯算法,考察所有可能的排列。程序如下:#include #include void search(int);void init(); /初始化void printresult(); /打印结果int isprime(int); /判断该数是否是素数void swap(int,int);

8、/交换am和aiint a21; /a数组存放素数环int main() init(); search(2); /递归搜索int isprime(int num) int i,k; k=sqrt(num); for(i=2;i=k;i+) if(num%i=0) return(0); return(1);void printresult() int i; for(i=1;i20) /当已经搜索到叶结点时 if(isprime(a1+a20) /如果a1+a20也是素数 printresult(); /输出当前解 return; else for(i=m;i=20;i+) /(排列树) swap

9、(m,i); /交换am和ai if(isprime(am-1+am) /判断am-1+am是否是素数 search(m+1); /递归搜索下一个位置 swap(m,i); /把am和ai换回来 void swap(int m, int i) int t; t=am; am=ai; ai=t;void init() int i; for(i=0;i21;i+) ai=i;7 迷宫问题给一个2020的迷宫、起点坐标和终点坐标,问从起点是否能到达终点。输入数据:.表示空格;X表示墙。程序如下:#include #include void search(int,int);int canplace(i

10、nt,int);void readdata(); /读入数据void printresult(); /打印结果int a2020; /a数组存放迷宫int s,t;int main() int row, col; readdata(); row=s/20; col=s%20; search(row,col); /递归搜索 printresult();void search(int row, int col) int r,c; arowcol=1; r=row; /左 c=col-1; if(canplace(r,c) /判断(r,c)位置是否已经走过 search(r,c); /递归搜索(r,

11、c) r=row+1; /下 c=col; if(canplace(r,c) /判断(r,c)位置是否已经走过 search(r,c); /递归搜索(r,c) r=row; /右 c=col+1; if(canplace(r,c) /判断(r,c)位置是否已经走过 search(r,c); /递归搜索(r,c) r=row-1; /上 c=col; if(canplace(r,c) /判断(r,c)位置是否已经走过 search(r,c); /递归搜索(r,c)void printresult() int i,j; for(i=0;i20;i+) for(j=0;j20;j+) printf(

12、%3d,aij); printf(n); void readdata() int i,j; for(i=0;i20;i+) for(j=0;j=0&row=0&col20&arowcol=0) return 1; else return 0;1. Floodfill给一个2020的迷宫和一个起点坐标,用广度优先搜索填充所有的可到达的格子。提示:参考第2题。2. 电子老鼠闯迷宫如下图1212方格图,找出一条自入口(2,9)到出口(11,8)的最短路本题给出完整的程序和一组测试数据。状态:老鼠所在的行、列。程序如下:#includevoid readdata(); /读入数据void init()

13、; /初始化int search(); /广搜,并在每一个可到达的每一个空格出填上最小步数int emptyopen(); /判栈是否为空:空:1;非空:0。int takeoutofopen(); /从栈中取出一个元素,并把该元素从栈中删除int canmoveto(int,int,int*,int*,int); /判能否移动到该方向,并带回坐标(r,c)int isaim(int row, int col); /判断该点是否是目标int used(int,int); /判断该点是否已经走过void addtoopen(int,int); /把该点加入到open表int a1212; /a存

14、放迷宫,0表示空格,-2表示墙。 /广搜时,未找到目标以前到达的空格,填上到达该点的最小步数int n; /n为迷宫边长,注:若大于12,必须修改一些参数,如a的大小int open20,head,tail,openlen=20; /open表int s,t; /起点和终点int main() int number; readdata(); /读取数据 init(); /初始化 number=search(); /广搜并返回最小步数 printf(%d,number); /打印结果int search() int u, row, col, r, c, i, num; while(!emptyo

15、pen() /当栈非空 u=takeoutofopen(); /从栈中取出一个元素,并把该元素从栈中删除 row=u/n; /计算该点的坐标 col=u%n; num=arowcol; /取得该点的步数 for(i=0;i4;i+) if(canmoveto(row,col,&r,&c,i) /判能否移动到该方向,并带回坐标(r,c) if(isaim(r,c) /如果是目标结点 return(num+1); /返回最小步数 if(!used(r,c) /如果(r,c)还未到达过 arc=num+1; /记录该点的最小步数 addtoopen(r,c); /把该点加入到open表 int em

16、ptyopen() if(head=tail) return(1); else return(0);int takeoutofopen() int u; if(head=tail) printf(errer: stack is empty); return(-1); u=openhead+; head=head%openlen; return(u);int canmoveto(int row, int col, int *p, int *q, int direction) int r,c; r=row; c=col; switch(direction) case 0: c-; /左 break

17、; case 1: r+; /下 break; case 2: c+; /右 break; case 3: r-; /上 *p=r; *q=c; if(r=n|c=n) /如果越界返回0 return(0); if(arc=0) /如果是空格返回1 return(1); return(0); /其余情况返回0int isaim(int row, int col) if(row*n+col=t) return(1); else return(0);int used(int row, int col) if(arowcol=0) / 0表示空格 return(0); else return(1);

18、void addtoopen(int row, int col) int u; u=row*n+col; opentail+= u; tail=tail%openlen;void readdata() int i,j,row,col; char str20; scanf(%d,&n); scanf(%d%d,&row,&col); /起点坐标 s=row*n+col; scanf(%d%d,&row,&col); /终点坐标 t=row*n+col; gets(str); for(i=0;in;i+) gets(str); for(j=0;jn;j+) if(strj=.) aij=0; /0

19、表示空格 else aij=-2; /2表示墙 void init() head=0; tail=1; open0=s;测试数据如下:12 10 7 1 8XXXXXXXXXXXXX.X.XXXX.X.XX.XX.X.XX.XXX.XX.X.X.XX.XXXXXXXXXXX.X.X.XX.XXX.XXXXX.X.XXXX.XXXX.X.XXXXXXXX.XXXXXXXXXXXXXXX注:测试数据可在运行时粘贴上去(点击窗口最左上角按钮,在菜单中选则“编辑”/“粘贴”即可)。想一想:此程序都存在哪些问题,如果openlen太小程序会不会出错,加入代码使程序能自动报出此类错误。3. 跳马给一个20

20、0200的棋盘,问国际象棋的马从给定的起点到给定的终点最少需要几步。Sample Input 0 0 1 1 Sample output 4 状态:马所在的行、列。程序如下:#includevoid readdata(); /读入数据void init(); /初始化int search(); /广度优先搜索int emptyopen(); /判栈是否为空:空:1;非空:0。long takeoutofopen(); /从栈中取出一个元素,并把该元素从栈中删除int canmoveto(int,int,int*,int*,int); /判能否移动到该方向,并带回坐标(r,c)int isaim

21、(int row, int col); /判断该点是否是目标int used(int,int); /判断该点是否已经走过void addtoopen(int,int); /把该点加入到open表int a200200,n=200; /a存放棋盘,n为迷宫边长long open2000,head,tail,openlen=2000; /open表1367long s,t; /起点和终点int search() long u; int row, col, r, c, i, num; while(!emptyopen() /当栈非空 u=takeoutofopen(); /从栈中取出一个元素,并把该

22、元素从栈中删除 row=u/n; /计算该点所在的行 col=u%n; /计算该点所在的列 num=arowcol; /取得该点的步数 for(i=0;i8;i+) if(canmoveto(row,col,&r,&c,i) /判能否移动到该方向,并带回坐标(r,c) if(isaim(r,c) /如果是目标结点 return(num+1); /返回最小步数 if(!used(r,c) /如果(r,c)还未到达过 arc=num+1; /记录该点的最小步数 addtoopen(r,c); /把该点加入到open表 return -1;int main() /为了让search()显示在一页内和

23、main函数换了以下 /一般的算法程序main函数写在最上面读起来更方便 int number; readdata(); /读取数据 init(); /初始化 number=search(); /广搜并返回最小步数 printf(%d,number); /打印结果int emptyopen() if(head=tail) return(1); else return(0);long takeoutofopen() long u; if(head=tail) printf(errer: stack is empty); return(-1); u=openhead+; head=head%ope

24、nlen; return(u);int used(int row, int col) if(arowcol=0) return(0); else return(1);void addtoopen(int row, int col) int u; if(head-tail)%openlen=1) printf(open table overflow); u=row; u=u*n+col; opentail+= u; tail=tail%openlen;void readdata() long row,col; scanf(%ld%ld,&row,&col); /起点坐标 s=row*n+col; scanf(%ld%ld,&row,&col); /终点坐标 t=row*n+col;void init() head=0; tail=1; open0=s;int isaim(int row, int col) if(row*n+col=t) return(1); else return(0);思考:参考第4题,改为用结构体表示状态写此程序。4. 独轮车独轮车的轮子上有5种颜色,每走一格颜色变化一次,独轮车只能往前推,也可以在原地旋转,每走一格,需要一个单位的时

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1