ACM程序设计竞赛例题文档格式.docx
- 文档编号:20462898
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:52
- 大小:37.26KB
ACM程序设计竞赛例题文档格式.docx
《ACM程序设计竞赛例题文档格式.docx》由会员分享,可在线阅读,更多相关《ACM程序设计竞赛例题文档格式.docx(52页珍藏版)》请在冰豆网上搜索。
else
{
a[m]=0;
//不选第m件物品
search(m+1);
//递归搜索下一件物品
a[m]=1;
}
voidcheckmax()
inti,weight=0,value=0;
for(i=0;
i<
n;
i++)
if(a[i]==1)//如果选取了该物品
{
weight=weight+w[i];
//累加重量
value=value+v[i];
//累加价值
}
if(weight<
=c)//若为可行解
if(value>
max)//且价值大于max
max=value;
//替换max
voidreaddata()
inti;
scanf("
%d%d"
&
w[i],&
v[i]);
//读入第i件物品重量和价值
voidprintresult()
printf("
%d"
max);
2.装载问题
有两艘船,载重量分别是c1、c2,n个集装箱,重量是wi(i=1…n),且所有集装箱的总重量不超过c1+c2。
确定是否有可能将所有集装箱全部装入两艘船。
提示:
求出不超过c1的最大值max,若总重量-max<
c2则能装入到两艘船。
3.堡垒问题(ZOJ1002)
如图城堡是一个4×
4的方格,为了保卫城堡,现需要在某些格子里修建一些堡垒。
城堡中的某些格子是墙,其余格子都是空格,堡垒只能建在空格里,每个堡垒都可以向上下左右四个方向射击,如果两个堡垒在同一行或同一列,且中间没有墙相隔,则两个堡垒都会把对方打掉。
问对于给定的一种状态,最多能够修建几个堡垒。
程序主要部分如下:
introw,col;
row=m/n;
//求第m个格子的行号
col=m%n;
//求第m个格子的列号
=n*n)
//该位置不放堡垒递归搜索下一个位置
if(canplace(m))//判断第m个格子是否能放堡垒
place(m);
//在第m个格子上放置一个堡垒
search(m+1);
//递归搜索下一个位置
takeout(m);
//去掉第m个格子上放置的堡垒
5.8皇后问题
在一个8×
8的棋盘里放置8个皇后,要求这8个皇后两两之间互相都不“冲突”。
math.h>
//打印结果
intcanplace(int,int);
//判断该位置能否放置皇后
voidplace(int,int);
//在该位置能否放置皇后
voidtakeout(int,int);
//把该位置放置皇后去掉
inta[8];
//a[i]存放第i个皇后的位置
=8)//当已经找出一组解时
printresult();
//输出当前结果
for(i=0;
8;
i++)//对当前行0到7列的每一个位置
if(canplace(m,i))//判断第m个格子是否能放堡垒
{
place(m,i);
//在(m,i)格子上放置一个皇后
search(m+1);
//递归搜索下一行
takeout(m,i);
//把(m,i)格子上的皇后去掉
}
intcanplace(introw,intcol)
row;
if(abs(i-row)==abs(a[i]-col)||a[i]==col)
return(0);
return
(1);
voidplace(introw,intcol)
a[row]=col;
voidtakeout(introw,intcol)
a[row]=-1;
inti,j;
for(j=0;
j<
j++)
if(a[i]==j)
printf("
A"
);
else
."
printf("
\n"
6.素数环问题
把从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数。
分析:
用回溯算法,考察所有可能的排列。
程序如下:
voidinit();
//初始化
intisprime(int);
//判断该数是否是素数
voidswap(int,int);
//交换a[m]和a[i]
inta[21];
//a数组存放素数环
init();
search
(2);
intisprime(intnum)
inti,k;
k=sqrt(num);
for(i=2;
=k;
if(num%i==0)
for(i=1;
=20;
%3d"
a[i]);
20)//当已经搜索到叶结点时
if(isprime(a[1]+a[20]))//如果a[1]+a[20]也是素数
printresult();
//输出当前解
return;
for(i=m;
i++)//(排列树)
swap(m,i);
if(isprime(a[m-1]+a[m]))//判断a[m-1]+a[m]是否是素数
//把a[m]和a[i]换回来
voidswap(intm,inti)
intt;
t=a[m];
a[m]=a[i];
a[i]=t;
voidinit()
21;
a[i]=i;
7.迷宫问题
给一个20×
20的迷宫、起点坐标和终点坐标,问从起点是否能到达终点。
输入数据:
’.’表示空格;
’X’表示墙。
voidsearch(int,int);
inta[20][20];
//a数组存放迷宫
ints,t;
row=s/20;
col=s%20;
search(row,col);
voidsearch(introw,intcol)
intr,c;
a[row][col]=1;
r=row;
//左
c=col-1;
if(canplace(r,c))//判断(r,c)位置是否已经走过
search(r,c);
//递归搜索(r,c)
r=row+1;
//下
c=col;
//右
c=col+1;
r=row-1;
//上
20;
printf("
a[i][j]);
scanf("
a[i][j]);
if(row>
=0&
&
row<
20&
col>
col<
a[row][col]==0)
return1;
return0;
1.Floodfill
20的迷宫和一个起点坐标,用广度优先搜索填充所有的可到达的格子。
参考第2题。
2.电子老鼠闯迷宫
如下图12×
12方格图,找出一条自入口(2,9)到出口(11,8)的最短路
本题给出完整的程序和一组测试数据。
状态:
老鼠所在的行、列。
#include<
intsearch();
//广搜,并在每一个可到达的每一个空格出填上最小步数
intemptyopen();
//判栈是否为空:
空:
1;
非空:
0。
inttakeoutofopen();
//从栈中取出一个元素,并把该元素从栈中删除
intcanmoveto(int,int,int*,int*,int);
//判能否移动到该方向,并带回坐标(r,c)
intisaim(introw,intcol);
//判断该点是否是目标
intused(int,int);
//判断该点是否已经走过
voidaddtoopen(int,int);
//把该点加入到open表
inta[12][12];
//a存放迷宫,0表示空格,-2表示墙。
//广搜时,未找到目标以前到达的空格,填上到达该点的最小步数
intn;
//n为迷宫边长,注:
若大于12,必须修改一些参数,如a的大小
intopen[20],head,tail,openlen=20;
//open表
//起点和终点
intnumber;
//读取数据
number=search();
//广搜并返回最小步数
number);
intsearch()
intu,row,col,r,c,i,num;
while(!
emptyopen())//当栈非空
u=takeoutofopen();
row=u/n;
//计算该点的坐标
col=u%n;
num=a[row][col];
//取得该点的步数
4;
if(canmoveto(row,col,&
r,&
c,i))//判能否移动到该方向,并带回坐标(r,c)
if(isaim(r,c))//如果是目标结点
return(num+1);
//返回最小步数
if(!
used(r,c))//如果(r,c)还未到达过
{
a[r][c]=num+1;
//记录该点的最小步数
addtoopen(r,c);
}
intemptyopen()
if(head==tail)
return
(1);
return(0);
inttakeoutofopen()
intu;
errer:
stackisempty"
return(-1);
u=open[head++];
head=head%openlen;
return(u);
intcanmoveto(introw,intcol,int*p,int*q,intdirection)
switch(direction)
case0:
c--;
break;
case1:
r++;
case2:
c++;
case3:
r--;
*p=r;
*q=c;
if(r<
0||r>
=n||c<
0||c>
=n)//如果越界返回0
if(a[r][c]==0)//如果是空格返回1
return(0);
//其余情况返回0
intisaim(introw,intcol)
if(row*n+col==t)
intused(introw,intcol)
if(a[row][col]==0)//0表示空格
voidaddtoopen(introw,intcol)
u=row*n+col;
open[tail++]=u;
tail=tail%openlen;
inti,j,row,col;
charstr[20];
scanf("
n);
row,&
col);
//起点坐标
s=row*n+col;
//终点坐标
t=row*n+col;
gets(str);
gets(str);
if(str[j]=='
.'
)
a[i][j]=0;
//0表示空格
a[i][j]=-2;
//-2表示墙
head=0;
tail=1;
open[0]=s;
测试数据如下:
1210718
XXXXXXXXXXXX
X......X.XXX
X.X.XX.....X
X.X.XX.XXX.X
X.X.....X..X
X.XXXXXXXXXX
X...X.X....X
X.XXX...XXXX
X.....X....X
XXX.XXXX.X.X
XXXXXXX..XXX
注:
测试数据可在运行时粘贴上去(点击窗口最左上角按钮,在菜单中选则“编辑”/“粘贴”即可)。
想一想:
此程序都存在哪些问题,如果openlen太小程序会不会出错,加入代码使程序能自动报出此类错误。
3.跳马
给一个200×
200的棋盘,问国际象棋的马从给定的起点到给定的终点最少需要几步。
SampleInput0011Sampleoutput4
状态:
马所在的行、列。
//广度优先搜索
longtakeoutofopen();
inta[200][200],n=200;
//a存放棋盘,n为迷宫边长
longopen[2000],head,tail,openlen=2000;
//open表1367
longs,t;
longu;
introw,col,r,c,i,num;
//计算该点所在的行
//计算该点所在的列
return-1;
intmain()//为了让search()显示在一页内和main函数换了以下
{//一般的算法程序main函数写在最上面读起来更方便
longtakeoutofopen()
if(a[row][col]==0)
if((head-tail)%openlen==1)
opentableoverflow"
u=row;
u=u*n+col;
longrow,col;
%ld%ld"
思考:
参考第4题,改为用结构体表示状态写此程序。
4.独轮车
独轮车的轮子上有5种颜色,每走一格颜色变化一次,独轮车只能往前推,也可以在原地旋转,每走一格,需要一个单位的时间
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ACM 程序设计 竞赛 例题