搜索试题集.docx

上传人:b****8 文档编号:9434506 上传时间:2023-02-04 格式:DOCX 页数:54 大小:32.42KB
下载 相关 举报
搜索试题集.docx_第1页
第1页 / 共54页
搜索试题集.docx_第2页
第2页 / 共54页
搜索试题集.docx_第3页
第3页 / 共54页
搜索试题集.docx_第4页
第4页 / 共54页
搜索试题集.docx_第5页
第5页 / 共54页
点击查看更多>>
下载资源
资源描述

搜索试题集.docx

《搜索试题集.docx》由会员分享,可在线阅读,更多相关《搜索试题集.docx(54页珍藏版)》请在冰豆网上搜索。

搜索试题集.docx

搜索试题集

说明:

本文件部分程序来自一些信息学奥赛的参考书,如早年的信息学高级本等。

时间关系,未能一一列出出处,请原作者见谅。

部分图尚未画出,争取尽快补上。

【execans.2为深度优先搜索,广度优先搜索类,及技巧性题目题解】

【题目1】N皇后问题(八皇后问题的扩展)

【题目2】排球队员站位问题

【题目3】把自然数N分解为若干个自然数之和。

【题目4】把自然数N分解为若干个自然数之积。

【题目5】马的遍历问题。

【题目6】加法分式分解

【题目7】地图着色问题

【题目8】在n*n的正方形中放置长为2,宽为1的长条块,

【题目9】找迷宫的最短路径。

(广度优先搜索算法)

【题目10】火车调度问题

【题目11】农夫过河

【题目12】七段数码管问题。

【题目13】把1-8这8个数放入下图8个格中,要求相邻的格(横,竖,对角线)上填的数不连续.

【题目14】在4×4的棋盘上放置8个棋,要求每一行,每一列上只能放置2个.

【题目15】迷宫问题.求迷宫的路径.(深度优先搜索法)

【题目16】一笔画问题

【题目17】城市遍历问题.

【题目18】棋子移动问题

【题目19】求集合元素问题(1,2x+1,3X+1类)

================================================================================[返回头部]

================================================================================

【题目】N皇后问题(含八皇后问题的扩展,规则同八皇后):

在N*N的棋盘上,放置N个皇后,要求每一横行每一列,每一对角线上均只能放置一个皇后,问可能的方案及方案数。

constmax=8;

vari,j:

integer;

a:

array[1..max]of0..max;{放皇后数组}

b:

array[2..2*max]ofboolean;{/对角线标志数组}

c:

array[-(max-1)..max-1]ofboolean;{\对角线标志数组}

col:

array[1..max]ofboolean;{列标志数组}

total:

integer;{统计总数}

procedureoutput;{输出}

vari:

integer;

begin

write('No.':

4,'[',total+1:

2,']');

fori:

=1tomaxdowrite(a[i]:

3);write('');

if(total+1)mod2=0thenwriteln;inc(total);

end;

functionok(i,dep:

integer):

boolean;{判断第dep行第i列可放否}

begin

ok:

=false;

if(b[i+dep]=true)and(c[dep-i]=true){and(a[dep]=0)}and

(col[i]=true)thenok:

=true

end;

proceduretry(dep:

integer);

vari,j:

integer;

begin

fori:

=1tomaxdo{每一行均有max种放法}

ifok(i,dep)thenbegin

a[dep]:

=i;

b[i+dep]:

=false;{/对角线已放标志}

c[dep-i]:

=false;{\对角线已放标志}

col[i]:

=false;{列已放标志}

ifdep=maxthenoutput

elsetry(dep+1);{递归下一层}

a[dep]:

=0;{取走皇后,回溯}

b[i+dep]:

=true;{恢复标志数组}

c[dep-i]:

=true;

col[i]:

=true;

end;

end;

begin

fori:

=1tomaxdobegina[i]:

=0;col[i]:

=true;end;

fori:

=2to2*maxdob[i]:

=true;

fori:

=-(max-1)tomax-1doc[i]:

=true;

total:

=0;

try

(1);

writeln('total:

',total);

end.

【测试数据】

n=8八皇后问题

No.[1]15863724No.[2]16837425

No.[3]17468253No.[4]17582463

No.[5]24683175No.[6]25713864

No.[7]25741863No.[8]26174835

No.[9]26831475No.[10]27368514

No.[11]27581463No.[12]28613574

No.[13]31758246No.[14]35281746

No.[15]35286471No.[16]35714286

No.[17]35841726No.[18]36258174

No.[19]36271485No.[20]36275184

No.[21]36418572No.[22]36428571

No.[23]36814752No.[24]36815724

No.[25]36824175No.[26]37285146

No.[27]37286415No.[28]38471625

No.[29]41582736No.[30]41586372

No.[31]42586137No.[32]42736815

No.[33]42736851No.[34]42751863

No.[35]42857136No.[36]42861357

No.[37]46152837No.[38]46827135

No.[39]46831752No.[40]47185263

No.[41]47382516No.[42]47526138

No.[43]47531682No.[44]48136275

No.[45]48157263No.[46]48531726

No.[47]51468273No.[48]51842736

No.[49]51863724No.[50]52468317

No.[51]52473861No.[52]52617483

No.[53]52814736No.[54]53168247

No.[55]53172864No.[56]53847162

No.[57]57138642No.[58]57142863

No.[59]57248136No.[60]57263148

No.[61]57263184No.[62]57413862

No.[63]58413627No.[64]58417263

No.[65]61528374No.[66]62713584

No.[67]62714853No.[68]63175824

No.[69]63184275No.[70]63185247

No.[71]63571428No.[72]63581427

No.[73]63724815No.[74]63728514

No.[75]63741825No.[76]64158273

No.[77]64285713No.[78]64713528

No.[79]64718253No.[80]68241753

No.[81]71386425No.[82]72418536

No.[83]72631485No.[84]73168524

No.[85]73825164No.[86]74258136

No.[87]74286135No.[88]75316824

No.[89]82417536No.[90]82531746

No.[91]83162574No.[92]84136275

total:

92

对于N皇后:

┏━━━┯━━┯━━┯━━┯━━┯━━┯━━┯━━┓

┃皇后N│4│5│6│7│8│9│10┃

┠───┼──┼──┼──┼──┼──┼──┼──┨

┃方案数│2│10│4│40│92│352│724┃

┗━━━┷━━┷━━┷━━┷━━┷━━┷━━┷━━┛

【题目】排球队员站位问题[返回头部]

┏━━━━━━━━┓图为排球场的平面图,其中一、二、三、四、五、六为位置编号,

┃        ┃二、三、四号位置为前排,一、六、五号位为后排。

某队比赛时,

┃        ┃一、四号位放主攻手,二、五号位放二传手,三、六号位放副攻

┠──┬──┬──┨手。

队员所穿球衣分别为1,2,3,4,5,6号,但每个队

┃四│三│二┃员的球衣都与他们的站位号不同。

已知1号、6号队员不在后排,

┠──┼──┼──┨2号、3号队员不是二传手,3号、4号队员不在同一排,5号、

┃五│六│一┃6号队员不是副攻手。

┗━━┷━━┷━━┛编程求每个队员的站位情况。

【算法分析】本题可用一般的穷举法得出答案。

也可用回溯法。

以下为回溯解法。

【参考程序】

typesset=setof1..6;

vara:

array[1..6]of1..6;

d:

array[1..6]ofsset;

i:

integer;

procedureoutput;{输出}

begin

ifnot((a[3]in[2,3,4])=(a[4]in[2,3,4]))then

begin{3,4号队员不在同一排}

write('number:

');fori:

=1to6dowrite(i:

8);writeln;

write('weizhi:

');fori:

=1to6dowrite(a[i]:

8);writeln;

end;

end;

proceduretry(i:

integer;s:

sset);{递归过程i:

第i个人,s:

哪些位置已安排人了}

var

j,k:

integer;

begin

forj:

=1to6dobegin{每个人都有可能站1-6这6个位置}

if(jind[i])andnot(jins)thenbegin

{j不在d[i]中,则表明第i号人不能站j位.j如在s集合中,表明j位已排人了}

a[i]:

=j;{第i人可以站j位}

ifi<6thentry(i+1,s+[j]){未安排妥,则继续排下去}

elseoutput;{6个人都安排完,则输出}

end;

end;

end;

begin

fori:

=1to6dod[i]:

=[1..6]-[i];{每个人的站位都与球衣的号码不同}

d[1]:

=d[1]-[1,5,6];

d[6]:

=d[6]-[1,5,6];{1,6号队员不在后排}

d[2]:

=d[2]-[2,5];

d[3]:

=d[3]-[2,5];{2,3号队员不是二传手}

d[5]:

=d[5]-[3,6];

d[6]:

=d[6]-[3,6];{5,6号队员不是副攻手}

try(1,[]);

end.

【题目】把自然数N分解为若干个自然数之和。

[返回头部]

【参考答案】

n│total5│7

6│11

7│15

10│42

100│190569291

【参考程序】

varn:

byte;num:

array[0..255]ofbyte;total:

word;

procedureoutput(dep:

byte);

varj:

byte;

begin

forj:

=1todepdowrite(num[j]:

3);writeln;inc(total);

end;

procedurefind(n,dep:

byte);{N:

待分解的数,DEP:

深度}

vari,j,rest:

byte;

begin

fori:

=1tondo{每一位从N到1去试}

ifnum[dep-1]<=ithen{保证选用的数大于前一位}

begin

num[dep]:

=i;

rest:

=n-i;{剩余的数进行下一次递归调用}

if(rest>0)thenbeginfind(rest,dep+1);end

elseifrest=0thenoutput(dep);{刚好相等则输出}

num[dep]:

=0;

end;

end;

begin{主程序}

writeln('inputn:

');readln(n);

fillchar(num,sizeof(num),0);

total:

=0;num[0]:

=0;

find(n,1);

writeln('sum=',total);

end.

【题目】[返回头部]

把自然数N分解为若干个自然数之积。

【参考程序】

varpath:

array[1..1000]ofinteger;

total,n:

integer;

procedurefind(k,sum,dep:

integer);{K:

}

varb,d:

Integer;

begin

ifsum=nthen{积等于N}

begin

write(n,'=',path[1]);

ford:

=2todep-1dowrite('*',path[d]);

writeln;inc(total);

exit;

end;

ifsum>nthenexit;{累积大于N}

forb:

=trunc(n/sum)+1downtokdo{每一种可能都去试}

begin

path[dep]:

=b;

find(b,sum*b,dep+1);

end;

end;

begin

readln(n);total:

=0;

find(2,1,1);writeln('total:

',total);

readln;

end.

【题目】[返回头部]

马的遍历问题。

在N*M的棋盘中,马只能走日字。

马从位置(x,y)处出发,把

棋盘的每一格都走一次,且只走一次。

找出所有路径。

【参考程序】{深度优先搜索法}

constn=5;m=4;

fx:

array[1..8,1..2]of-2..2=((1,2),(2,1),(2,-1),(1,-2),(-1,-2),(-2,-1),

(-2,1),(-1,2));{八个方向增量}

var

dep,i:

byte;x,y:

byte;

cont:

integer;{统计总数}

a:

array[1..n,1..m]ofbyte;{记录走法数组}

procedureoutput;{输出,并统计总数}

varx,y:

byte;

begin

cont:

=cont+1;writeln;

writeln('count=',cont);

fory:

=1tondobegin

forx:

=1tomdowrite(a[y,x]:

3);writeln;

end;{readln;halt;}

end;

procedurefind(y,x,dep:

byte);

vari,xx,yy:

integer;

begin

fori:

=1to8do

begin

xx:

=x+fx[i,1];yy:

=y+fx[i,2];{加上方向增量,形成新的坐标}

if((xxin[1..m])and(yyin[1..n]))and(a[yy,xx]=0)then

{判断新坐标是否出界,是否已走过?

}

begin

a[yy,xx]:

=dep;{走向新的坐标}

if(dep=n*m)thenoutput

elsefind(yy,xx,dep+1);{从新坐标出发,递归下一层}

a[yy,xx]:

=0{回溯,恢复未走标志}

end;

end;

end;

begin

cont:

=0;

fillchar(a,sizeof(a),0);

dep:

=1;

writeln('inputy,x');readln(y,x);

{x:

=1;y:

=1;}

if(y>n)or(x>m)thenbeginwriteln('x,yerror!

');halt;end;

a[y,x]:

=1;

find(y,x,2);

ifcont=0thenwriteln('Noanswer!

')elsewrite('TheEnd!

');

readln;

end.

【题目】[返回头部]

加法分式分解。

如:

1/2=1/4+1/4.找出所有方案。

输入:

NMN为要分解的分数的分母

M为分解成多少项

【参考程序】

programfenshifenjie;

constnums=5;

var

t,m,dep:

integer;

n,maxold,max,j:

longint;

path:

array[0..nums]oflongint;

maxok,p:

boolean;

sum,sum2:

real;

procedureprint;

vari:

integer;

begin

t:

=t+1;

ifmaxok=truethenbeginmaxold:

=path[m];maxok:

=false;end;

write('NO.',t);

fori:

=1tomdowrite('',path[i]:

4);writeln;

ifpath[1]=path[m]thenbeginwriteln('Ok!

total:

',t:

4);readln;halt;end;

end;

procedureinput;

begin

writeln('inputN:

');readln(n);

writeln('inputM(M<=',nums:

1,'):

');readln(m);

if(n<=0)or(m<=0)or(m>4)or(n>maxlongint)

thenbeginwriteln('InvalidInput!

');readln;halt;end;

end;

functionsum1(ab:

integer):

real;

vara,b,c,d,s1,s2:

real;

i:

integer;

begin

ifab=1then

sum1:

=1/path[1]

else

begin

a:

=path[1];

b:

=1;

c:

=path[2];

d:

=1;

fori:

=1toab-1do

begin

s2:

=(c*b+a*d);

s1:

=(a*c);

a:

=s1;

b:

=s2;

c:

=path[i+2];

end;

sum1:

=s2/s1;

end;

end;

procedureback;

begin

dep:

=dep-1;

ifdep<=m-2thenmax:

=maxold;

sum:

=sum-1/path[dep];

j:

=path[dep];

end;

procedurefind;

begin

repeat

dep:

=dep+1;

j:

=path[dep-1]-1;

p:

=false;

repeat

j:

=j+1;

if(dep<>m)and(j<=max)then

if(sum+1/j)>=1/nthenp:

=false

elsebegin

p:

=true;

path[dep]:

=j;

sum:

=sum+1/path[dep];

end

elseifj>maxthenback;

ifdep=mthenbegin

path[dep]:

=j;

sum2:

=sum1(m);

if(sum2)>1/nthenp:

=false;

if(sum2)=1/nthenbeginprint;

max:

=j;

back;

end;

if(sum2<1/n)thenback;

if(j>=max)thenback;

end;

untilp

untildep=0;

end;

begin

INPUT;

maxok:

=true;

fort:

=0tomdopath[t]:

=n;

dep:

=0;t:

=0;sum:

=0;

max:

=maxlongint;

find;

readln;

end.

【题目】[返回头部]

地图着色问题

【参考程序1】

constlin:

array[1..12,1..12]of0..1{区域相邻数组

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 医学

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

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