搜索算法个人总结pascal.docx

上传人:b****5 文档编号:6355158 上传时间:2023-01-05 格式:DOCX 页数:34 大小:88.37KB
下载 相关 举报
搜索算法个人总结pascal.docx_第1页
第1页 / 共34页
搜索算法个人总结pascal.docx_第2页
第2页 / 共34页
搜索算法个人总结pascal.docx_第3页
第3页 / 共34页
搜索算法个人总结pascal.docx_第4页
第4页 / 共34页
搜索算法个人总结pascal.docx_第5页
第5页 / 共34页
点击查看更多>>
下载资源
资源描述

搜索算法个人总结pascal.docx

《搜索算法个人总结pascal.docx》由会员分享,可在线阅读,更多相关《搜索算法个人总结pascal.docx(34页珍藏版)》请在冰豆网上搜索。

搜索算法个人总结pascal.docx

搜索算法个人总结pascal

2011.10.17总结

(1-5题为今天重写一次,其下所表示的提交次数为今天重写的提交次数,其他题提交次数为原来的次数,部分不详,题号前加星号表示未AC)

1·N皇后(位运算版)

这个是看了标程后写的,很有意思很巧妙的做法,也很强大,一次wa,是因为没写inc(sum),。

①(只输出结果数目)

programquen;

var

k,sum,n:

longint;

proceduredfs(row,l,r:

longint);//row:

列l,r:

两条对角线

var

pos,p:

longint;

begin

ifrow<>kthen

begin

pos:

=kandnot(lorrorrow);//表示需要放皇后的的位子

whilepos<>0do//有皇后要放

begin

p:

=posand(notpos+1);//取最右边的1//p表示某个可以放上皇后的地方

pos:

=pos-p;//放上皇后

dfs(row+p,(l+p)shl1,(r+p)shr1);//回溯,注意对角线的处理

end;

end

elseinc(sum);

end;

begin

readln(n);

k:

=(1shln)-1;//每一位都是1,目标状态

dfs(0,0,0);

writeln(sum);

end.

②(输出前3种方案,tyvj080)

programquen{输出前3种解};

var

k,sum,n,i,t:

longint;

a:

array[0..14]oflongint;

proceduredfs(dep,row,l,r:

longint);//dep:

层数row:

列l,r:

两条对角线

var

pos,p,i:

longint;

begin

ifdep>nthen//决策有效

begin

inc(sum);

ifsum<=3then

begin

fori:

=1tondo

write(a[i],'');//输出决策

writeln;

end;

end

elsebegin

fori:

=1tondo//第i位是否可以放皇后

begin

p:

=(1shl(i-1));//二进制决策

pos:

=pand(roworlorr);//pos记录冲突

if(pos=0)//没有冲突

thenbegin

a[dep]:

=i;//记录决策

dfs(dep+1,row+p,(l+p)shl1,(r+p)shr1);//下一层递归

end;

end;

end

end;

begin

readln(n);

k:

=(1shln)-1;//每一位都是1,目标状态

fori:

=1tondo

begin

a[1]:

=i;//初始化第一行,有n个状态

t:

=1shl(i-1);

dfs(2,t,tshl1,tshr1);

end;

writeln(sum);

end.

2.计算细胞数

一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。

如:

阵列

0234500067

1034560500

2045600671

0000000089  

有4个细胞

输入格式InputFormat

第一行 :

两个数字MN(1<=M<=501<=N<80)表示该阵列有M行N列 

从第2行到第M+1行 每行有连续的N个字符

输出格式OutputFormat

一行:

细胞个数

似乎我写出来的不是标准的搜索……

//思路:

以细胞中的一个点为起点,将他及他周围的不为0的点都改为0,然后找下一个。

//提交情况:

一次AC

programtyvj1127;

var

n,m,re:

longint;

a:

array[1..100,1..100]oflongint;

procedureinit;

begin

assign(input,'tyvj1127.in');

assign(output,'tyvj1127.out');

reset(input);

rewrite(output);

end;

procedurechange(i,j:

longint);

var

k,l:

longint;

begin

a[i,j]:

=0;

ifi>1thenifa[i-1,j]>0thenchange(i-1,j);

ifa[i+1,j]>0thenchange(i+1,j);

ifj>1thenifa[i,j-1]>0thenchange(i,j-1);

ifa[i,j+1]>0thenchange(i,j+1);

end;

procedureprepare;

var

i,j:

longint;

k:

char;

begin

readln(n,m);

fori:

=1tondo

begin

forj:

=1tomdo

begin

read(k);

val(k,a[i,j]);

end;

readln;

end;

re:

=0;

fori:

=1tondo

forj:

=1tomdo

begin

ifa[i,j]<>0thenbeginchange(i,j);re:

=re+1;end;

end;

writeln(re);

end;

procedureoutit;

begin

close(input);

close(output);

end;

begin

init;

prepare;

outit;

end.

3·滑雪

trs喜欢滑雪。

他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。

为了得到更快的速度,滑行的路线必须向下倾斜。

 例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。

例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。

输入文件

第1行:

两个数字r,c(1<=r,c<=100),表示矩阵的行列。

第2..r+1行:

每行c个数,表示这个矩阵。

输出文件

仅一行:

输出1个整数,表示可以滑行的最大长度。

样例输入SampleInput

55

12345

161718196

152425207

142322218

131211109

样例输出SampleOutput

25

记忆化搜索,也没设么好说的,就是刚开始的时候写出来总是无法跳出递归……

 提交情况:

1次WA 原因:

没删input和output 

programski;

const

maxn=100;

dx:

array[1..4]oflongint=(0,-1,0,1);

dy:

array[1..4]oflongint=(1,0,-1,0);

var

a,f:

array[1..maxn,1..maxn]oflongint;

max,r,c,i,j:

longint;

functionbest(x,y:

longint):

longint;

var

i,x2,y2:

longint;

begin

iff[x,y]>0thenexit(f[x,y]);

best:

=1;

fori:

=1to4do

begin

x2:

=x+dx[i];

y2:

=y+dy[i];

if(x2<=r)and(x2>=1)and(y2<=c)and(y2>=1)and(a[x,y]>a[x2,y2])then

begin

ifbest(x2,y2)+1>bestthen

best:

=best(x2,y2)+1;

end;

end;

f[x,y]:

=best;

end;

begin

readln(r,c);

fori:

=1tordo

forj:

=1tocdoread(a[i,j]);

fillchar(f,sizeof(f),0);

max:

=0;

fori:

=1tordo

forj:

=1tocdobegin

ifbest(i,j)>maxthenmax:

=best(i,j);

end;

writeln(max);

end.

**4·Sramoc问题(SramocProblem)

源程序名sramoc.?

?

?

(pas,c,cpp)

可执行文件名sramoc.exe

输入文件名sramoc.in

输出文件名sramoc.out

问题描述:

Sramoc(K,M)表示用数字0、1、2…、K-1组成的自然数中能被M整除的最小数。

给定K、M,求Sramoc(K,M)。

例如K=2,M=7的时候,Sramoc(2,7)=1001。

输入格式:

从文件SRAMOC.DAT读入数据。

第一行为两个整数K、M满足2<=K<=10、1<=M<=1000。

输出格式:

输出Sramoc(K,M)到SRAMOC.OUT。

样例

SRAMOC.DAT

SRAMOC.OUT

27

1001

思路:

广搜,从1位数的余数出发,不停扩展,生成新余数,直到余数0第一次出现

提交情况:

一次90分 原因直接扩展有一组的答案超出了qword的最大值……

改进思路,每次只记录一位。

90分程序如下:

programsramoc;

var

k,m:

longint;

d:

array[0..100000]ofqword;

hash:

array[0..2000]oflongint;

procedureinit;

begin

assign(input,'sramoc.in');

assign(output,'sramoc.out');

reset(input);

rewrite(output);

end;

procedureprepare;

var

i,j:

longint;

begin

readln(k,m);

end;

procedureoutit;

begin

close(input);

close(output);

halt;

end;

proceduremain;

var

l,r,i,j:

longint;

x,y:

qword;

begin

l:

=0;r:

=0;

fillchar(hash,sizeof(hash),0);

fori:

=1tok-1do

begin

d[i]:

=i;

ifd[i]modm=0thenbeginwriteln(d[i]);outit;end;

r:

=r+1;

hash[d[i]modm]:

=1;

end;

repeat

l:

=l+1;

x:

=d[l];

fori:

=0tok-1do

begin

y:

=x*10+i;

ifymodm=0thenbeginwriteln(y);outit;end;

ifhash[ymodm]=0thenbegin

r:

=r+1;

d[r]:

=y;

hash[ymodm]:

=1;

end;

end;

untill=r;

end;

begin

init;

prepare;

main;

outit;

end.

**5·黑白棋游戏

源程序名game.?

?

?

(pas,c,cpp)

可执行文件名game.exe

输入文件名game.in

输出文件名game.out

【问题描述】

黑白棋游戏的棋盘由4×4方格阵列构成。

棋盘的每一方格中放有1枚棋子,共有8枚白棋子和8枚黑棋子。

这16枚棋子的每一种放置方案都构成一个游戏状态。

在棋盘上拥有1条公共边的2个方格称为相邻方格。

一个方格最多可有4个相邻方格。

在玩黑白棋游戏时,每一步可将任何2个相邻方格中棋子互换位置。

对于给定的初始游戏状态和目标游戏状态,编程计算从初始游戏状态变化到目标游戏状态的最短着棋序列。

【输入】

输入文件共有8行。

前四行是初始游戏状态,后四行是目标游戏状态。

每行4个数分别表示该行放置的棋子颜色。

“0”表示白棋;“1”表示黑棋。

【输出】

输出文件的第一行是着棋步数n。

接下来n行,每行4个数分别表示该步交换棋子的两个相邻方格的位置。

例如,abcd表示将棋盘上(a,b)处的棋子与(c,d)处的棋子换位。

【样例】

game.ingame.out

11114

00001222

11101424

00103242

10104344

0101

1010

0101

广搜,用位运算记录及更改状态,分别处理上下交换和左右交换.

提交情况:

4次——60分前3次提交分别是输出格式不对,第4,8,12位没有单独处理

60分的程序如下(4组方案不对):

programgame;

type

mm=record

num,st,c1,c2,cn:

longint;

end;

const

p:

array[1..16,1..2]oflongint=((4,4),(4,3),(4,2),(4,1),(3,4),(3,3),(3,2),(3,1),(2,4),(2,3),(2,2),(2,1),(1,4),(1,3),(1,2),(1,1));

var

ss,tt:

array[0..4,0..4]oflongint;

d:

array[0..1000000]ofmm;

s,t:

longint;

procedureinit;

begin

assign(input,'game.in');

assign(output,'game.out');

reset(input);

rewrite(output);

end;

procedureprepare;

var

i,j,k,w:

longint;

s1,c:

string;

begin

s:

=0;t:

=0;

fori:

=1to4do

begin

readln(s1);

forj:

=1to4do

begin

c:

=s1[j];

val(c,ss[i,j]);

k:

=17-((i-1)*4+j);

s:

=s+(ss[i,j]shl(k-1));

end;

end;

fori:

=1to4do

begin

readln(s1);

forj:

=1to4do

begin

c:

=s1[j];

val(c,tt[i,j]);

k:

=17-((i-1)*4+j);

t:

=t+(tt[i,j]shl(k-1));

end;

end;

end;

procedureoutit;

begin

close(input);

close(output);

halt;

end;

procedureprint(x:

longint);

var

i,last,j,k:

longint;

begin

ifx=1thenexit;

last:

=d[x].st;

j:

=d[x].c2;

k:

=d[x].c1;

write(p[j,1],p[j,2]);

writeln(p[k,1],p[k,2]);

print(last);

end;

proceduremain;

var

i,j,l,r,x,y:

longint;

hash:

array[0..100000]ofboolean;

begin

fillchar(hash,sizeof(hash),false);

hash[s]:

=true;

d[1].num:

=s;

d[1].cn:

=0;

l:

=0;r:

=1;

repeat

l:

=l+1;

x:

=d[l].num;

fori:

=1to15do

begin

if(((xshr(i-1))and1)<>((xshr(i))and1))and(i<>4)and(i<>8)and(i<>12)

thenbegin

y:

=xxor(1shl(i-1));

y:

=yxor(1shl(i));

ifhash[y]=falsethen

begin

r:

=r+1;

d[r].num:

=y;

d[r].st:

=l;

d[r].c1:

=i;

d[r].c2:

=i+1;

d[r].cn:

=d[l].cn+1;

hash[y]:

=true;

end;

ify=tthenbeginwriteln(d[r].cn);print(r);outit;end;

end;

if(i<=12)and(((xshr(i-1))and1)<>((xshr(i+4-1))and1))

thenbegin

y:

=xxor(1shl(i-1));

y:

=yxor(1shl(i+3));

ifhash[y]=falsethen

begin

r:

=r+1;

d[r].num:

=y;

d[r].st:

=l;

d[r].c1:

=i;

d[r].c2:

=i+4;

d[r].cn:

=d[l].cn+1;

hash[y]:

=true;

end;

ify=tthenbeginwriteln(d[r].cn);print(r);outit;end;

end;

end;

untill>=r;

end;

begin

init;

prepare;

main;

outit;

end.

6·迷宫(maze.pas/c/cpp)

【问题描述】

电脑游戏中有许多令人头疼的迷宫,会花费玩家相当多的时间,你通过秘笈获得了游戏迷宫的地图,你希望找到最短的一条走出迷宫的道路,并且想知道一共有多少条最短的道路,但是由于地图非常庞大,所以你不能在短时间找出这些道路,因此,你需要编写一个程序来找出这些最短的道路,并且统计一下一共有多少条这样的道路。

例如,对于下图所示的迷宫:

S

X

X

X

X

E

X表示障碍物,不可以通过,S表示迷宫的入口,E表示迷宫的出口。

显然,从入口到出口至少需要走6步,而长度为6的道路一共有两条。

输入文件maze.in,第一行是一个整数n(1≤n≤25),表示迷宫是一个n×n的矩阵。

以下n行每行有n个字符来描述地图,“.”表示可以通过,“X”表示不可以通过,“S”表示迷宫的入口,“E”表示迷宫的出口。

(注意:

所有的字母均为大写)。

输出文件maze.out包括两行,第一行包含一个整数,表示从入口到出口走的最短距离。

第二行包含一个整数,表示最短路径的调数,答案保证小于231。

【样例输入】

4

…S

.XX.

.XX.

E...

【样例输出】

6

2

写两个广搜先找距离再找条数(此程序用动规的思想,写的类似广搜)

提交情况:

一次ac

programmaze;

var

map:

array[0..50,0..50]ofchar;

a,b:

array[0..850,0..50]oflongint;

n,sx,sy,ex,ey:

longint;

procedureinit;

begin

assign(input,'maze.in');

assign(output,'maze.out');

reset(input);

rewrite(output);

end;

procedureprepare;

var

i,j:

longint;

begin

readln(n);

fori:

=1tondo

begin

forj:

=1tondo

begin

read(map[i,j]);

ifmap[i,j]='S'thenbeginsx:

=i;sy:

=j;end;

ifmap[i,j]='E'thenbeginex:

=i;ey:

=j;end;

end;

readln;

end;

end;

procedureoutit;

begin

close(input);

close(output);

end;

procedurechang;

var

i,j,f,t:

longint;

dui:

array[1..2000,1..2]oflongint;

begin

fori:

=1tondo

forj:

=1tondo

a[i,j]:

=-1;

f:

=0;t:

=1;

a[sx,sy]:

=0;

dui[1,1]:

=sx;dui[1,2]:

=sy;

repeat

f:

=f+1;

i:

=dui[f,1];

j:

=dui[f,2];

if(a[i-1,j]<0)and(map[i-1,j]<>'X')

thenbegin

t:

=t+1;

a[i-1,j]:

=a[i,j]+1;

dui[t,1]:

=i-1;dui[t,2]:

=j;

end;

if(a[i+1,j]<0)and(map[i+1,j]<>'X')

thenbegin

t:

=t+1;

a[i+1,j]:

=a[i,j]+1;

dui[t,1]:

=i+1;dui[t,2]:

=j;

end;

if(a[i,j-1]<0)and(map[i,j-1]<>'X')

thenbegin

t:

=t+1;

a[i,j-1]:

=a[i,j]+1;

dui[t,1]:

=i;dui[t,2]:

=j-1;

end;

if(a[i,j+1]<0)and(map[i,j+1]<>'X')

thenbegin

t:

=t+1;

a[i,j+1]:

=a[i,j]+1;

dui[t,1]:

=i;dui[t,2]:

=j+1;

end;

ifa[ex,ey]>0thenexit;

untilf>=t;

end;

procedurelujin;

var

i,j,f,t:

longint;

dui:

array[1..2000,1..2]oflongint;

k:

array[0..50,0..50]ofboolean;

be

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

当前位置:首页 > 党团工作 > 入党转正申请

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

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