您的位置:首页

二、搜索

2017-07-11 08:50 162 查看
1.红与黑(codevs2806)

题目网址:http://codevs.cn/problem/2806/

代码:

var

s:array[0..21,0..21] of char;

i,j,sum,w,c,x,y:longint;

procedure m(a,b:longint);

begin

inc(sum);

s[a,b]:='#';

if(s[a+1,b]='.') then

begin

m(a+1,b);

end;

if(s[a-1,b]='.') then

begin

m(a-1,b);

end;

if(s[a,b+1]='.') then

begin

m(a,b+1);

end;

if(s[a,b-1]='.') then

begin

m(a,b-1);

end;

end;

begin

readln(w,c);

while (w<>0) and (c<>0) do

begin

fillchar(s,sizeof(s),0);

for i:=1 to c do

begin

for j:=1 to w do

begin

read(s[i,j]);

if (s[i,j]='@') then

begin

x:=i;

y:=j;

end;

end;

readln;

end;

sum:=0;

m(x,y);

writeln(sum);

readln(w,c);

end;

end.

2.八数码难题

题目网址:http://codevs.cn/problem/1225/

分析:

这题值得说的是康托展开。全排列与整数的映射,挺实用的。

接下来就是普通的BFS了。和用HASH表判重

代码:

type arr=array [1..9] of longint;

var a:array [1..30000] of arr;

fac:array [0..10] of longint;

step,space:array [0..30000] of longint;

i,front,tail:longint;

s:string;

hash:array [1..400000] of boolean;

function cantor(a:arr):longint;

var i,j:longint;

k:arr;

begin

fillchar(k,sizeof(k),0);

cantor:=0;

for i:=1 to 9 do

for j:=i+1 to 9 do

if a[i]>a[j] then inc(k[i]);

for i:=1 to 9 do cantor:=cantor+k[i]*fac[9-i];

cantor:=cantor+1;

end;

procedure exchange(s,t:longint);

var tmp:arr;

num,fun,i:longint;

begin

tmp:=a[front];

fun:=tmp[s]; tmp[s]:=tmp[t];tmp[t]:=fun;

num:=cantor(tmp);

if num=46686 then

begin

write(step[front]+1);

halt;

end;

if not hash[num] then

begin

inc(tail);

a[tail]:=tmp;

hash[num]:=true;

space[tail]:=t;

step[tail]:=step[front]+1;

end;

end;

begin

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

readln(s);

fac[0]:=1;

for i:=1 to 9 do fac[i]:=i*fac[i-1];

for i:=1 to 9 do

begin

a[1][i]:=ord(s[i])-ord('0');

if a[1][i]=0 then space[1]:=i;

end;

hash[cantor(a[1])]:=true;

front:=1;

tail:=1;

step[1]:=0;

while front<=tail do

begin

if space[front]<=6 then exchange(space[front],space[front]+3);

if space[front]>=4 then exchange(space[front],space[front]-3);

if ((space[front]-1)mod 3)>0 then exchange(space[front],space[front]-1);

if ((space[front]-1)mod 3)<2 then exchange(space[front],space[front]+1);

inc(front);

end;

end.

3.武士风度的牛
题目网址:http://codevs.cn/problem/1411/

分析:利用BFS求无权最短路径

代码:

var

a:array[1..150,1..150] of char;

b:array[1..22500,1..3] of longint;

i,j,m,n,x,y,m1,n1,m2,n2,f,r:longint;

begin

readln(n,m);

for i:=1 to m do

begin

for j:=1 to n do

begin

read(a[i,j]);

if a[i,j]='K' then

begin

m1:=i;

n1:=j;

end;

if a[i,j]='H' then

begin

m2:=i;

n2:=j;

end;

end;

readln;

end;

f:=1;

r:=1;

a[m2,n2]:='*';

b[f,1]:=m2;

b[f,2]:=n2;

b[f,3]:=0;

repeat

x:=b[f,1];

y:=b[f,2];

if (x=m1) and (y=n1) then

begin

writeln(b[f,3]);

end;

if (x-1>0) and (y-2>0) and (a[x-1,y-2]<>'*') then

begin

inc(r);

b[r,1]:=x-1;

b[r,2]:=y-2;

b[r,3]:=b[f,3]+1;

a[x-1,y-2]:='*';

end;

if (x-2>0) and (y-1>0) and (a[x-2,y-1]<>'*') then

begin

inc(r);

b[r,1]:=x-2;

b[r,2]:=y-1;

b[r,3]:=b[f,3]+1;

a[x-2,y-1]:='*';

end;

if (x-2>0) and (y+1<n) and (a[x-2,y+1]<>'*') then

begin

inc(r);

b[r,1]:=x-2;

b[r,2]:=y+1;

b[r,3]:=b[f,3]+1;

a[x-2,y+1]:='*';

end;

if (x-1>0) and (y+2<n) and (a[x-1,y+2]<>'*') then

begin

inc(r);

b[r,1]:=x-1;

b[r,2]:=y+2;

b[r,3]:=b[f,3]+1;

a[x-1,y+2]:='*';

end;

if (x+1<m) and (y-2>0) and (a[x+1,y-2]<>'*') then

begin

inc(r);

b[r,1]:=x+1;

b[r,2]:=y-2;

b[r,3]:=b[f,3]+1;

a[x+1,y-2]:='*';

end;

if (x+2<m) and (y+1<n) and (a[x+2,y+1]<>'*') then

begin

inc(r);

b[r,1]:=x+2;

b[r,2]:=y+1;

b[r,3]:=b[f,3]+1;

a[x+2,y+1]:='*';

end;

if (x+2<m) and (y-1>0) and (a[x+2,y-1]<>'*') then

begin

inc(r);

b[r,1]:=x+2;

b[r,2]:=y-1;

b[r,3]:=b[f,3]+1;

a[x+2,y-1]:='*';

end;

if (x+1<m) and (y+2<n) and (a[x+1,y+2]<>'*') then

begin

inc(r);

b[r,1]:=x+1;

b[r,2]:=y+2;

b[r,3]:=b[f,3]+1;

a[x+1,y+2]:='*';

end;

inc(f);

until f>r;

end.

4.最大黑区域

描写叙述:

二值图像是由黑白两种像素组成的矩形点阵,图像识别的一个操作是求出图像中最大黑区域的面积。请设计一个程序完毕二值图像的这个操作。黑区域由黑像素组成。一个黑区域中的每一个像素至少与该区域中的还有一个像素相邻,规定一个像素仅与其上、下、左、右的像素相邻。两个不同的黑区域没有相邻的像素。

一个黑区域的面积是其所包括的像素的个数。

输入格式:

输入由多个測试例组成。

每一个測试例的第一行含两个整数n和m, (1 <=n,m<=100), 分别表示二值图像的行数与列数,后面紧跟着n行,每行含m个整数0或1,当中第i行表示图像的第i行的m个像素,0表示白像素,1表示黑像素。

同一行的相邻两个整数之间用一个空格隔开,两个測试例之间用一个空行隔开,最后一个測试例之后隔一个空行,再接的一行含有两个整数0,标志输入的结束。

输出格式:

每一个測试例相应一行输出,含一个整数,表示相应的图像中最大黑区域的面积。

输入例子:

5 6

0 1 1 0 0 1

1 1 0 1 0 1

0 1 0 0 1 0

0 0 0 1 1 1

1 0 1 1 1 0

0 0

输出例子:

7

分析:利用BFS求连通块

代码:

var

a:array [1..101,1..101] of 0..1;

f:array [1..101,1..101] of boolean;

i,j,n,m,x,m1,n1,max:longint;

ch:string;

procedure js(m1,n1:longint);

begin

if (m1>m) or (n1>n) then exit;

a[m1,n1]:=0;

if (m1>1)and(a[m1-1,n1]<>0) then

begin

js(m1-1,n1);

end;

if (n1>1)and(a[m1,n1-1]<>0) then

begin

js(m1,n1-1);

end;

if (a[m1,n1+1]<>0) then

begin

js(m1,n1+1);

end;

if (a[m1+1,n1]<>0) then

begin

js(m1+1,n1);

end;

inc(x);

exit;

end;

begin

max:=0;

x:=0;

readln(m,n);

for i:=1 to m do

begin

for j:=1 to n do

begin

read(a[i,j]);

end;

readln;

end;

for i:=1 to m do

begin

for j:=1 to n do

begin

if a[i,j]<>0 then js(i,j);

if max<x then max:=x;

x:=0;

end;

end;

writeln(max);

end.

5.解救ice-cream

描写叙述 Description

给你一张坐标图,s为Tina的初始位置。m为Ice-cream home的位置。‘.’为路面,Tina在上面,每单位时间能够移动一格;‘#’为草地,Tina在上面,每两单位时间能够移动一格(建议不要模仿—毕竟Tina还小);‘o’是障碍物,Tina不能在它上面行动。也就是说,Tina仅仅能在路面或草地上行走,必须绕过障碍物。并到达冰淇淋店。但是…………不保证到达时,冰淇淋还未融化,所以……就请聪明的你……选择最佳的方案啦…………假设。Tina到的时候,冰淇淋已经融化完了,那她但是会哭的。

输入格式 Input Format

依次输入冰淇淋的融化时间t(0<t<1000),坐标图的长x,宽y(5<=x,y<=25){太长打起来好累……},和整张坐标图。

输出格式 Output Format

推断依照最优方案能否够赶在冰淇淋融化之前到达冰淇淋店(注:当T=最优方案所用时间,则推断为未赶到),如赶到,输出所用时间;如未赶到。输出Tina的哭声——“55555”(不包含引號)。

例子输入 Sample Input

11

10

8

......s...

..........

#ooooooo.o

#.........

#.........

#.........

#.....m...

#.........

例子输出 Sample Output

10

时间限制 Time Limitation

各个測试点1s

分析:利用BFS求加权单源最佳路径

借用王大牛代码:
program P1340;

type

rec=record

x,y:longint;

di:longint;

time:longint;

end;

var

s:array[1..100000,1..4] of longint;

time:array[1..30,1..30] of longint;

a:array[1..30,1..30] of char;

sb1,sb2:char;

b:array[1..30,1..30] of longint;

q,open,closed,t,x,y,x0,y0,x1,y1,i,j,k,l,m:longint;

begin

q:=maxlongint;

assign(input,'haha.in');

reset(input);

readln(t);

read(x,y);

for j:=1 to y do

begin

read(sb1,sb2);

for i:=1 to x do

begin

read(a[i,j]);

if a[i,j]='.'then b[i,j]:=1

else if a[i,j]='#'then b[i,j]:=2

else if a[i,j]='o' then b[i,j]:=maxlongint

else if a[i,j]='s' then begin x0:=i;y0:=j; b[i,j]:=1;end

else if a[i,j]='m' then begin x1:=i;y1:=j; b[i,j]:=0;end;

end;

end;

close(input);

for j:=1 to y do

for i:=1 to x do

time[i,j]:=maxlongint;

closed:=0; open:=1;

s[1,1]:=x0; s[1,2]:=y0; s[1,3]:=0; s[1,4]:=0;

repeat

repeat

inc(closed);

if time[s[closed,1],s[closed,2]]>s[closed,4] then begin

time[s[closed,1],s[closed,2]]:=s[closed,4];

if (s[closed,3]<>1)and(s[closed,1]<x)and(a[s[closed,1]+1,s[closed,2]]<>'o')then begin

inc(open);

s[open,1]:=s[closed,1]+1;

s[open,2]:=s[closed,2];

s[open,3]:=3;

s[open,4]:=s[closed,4]+b[s[closed,1],s[closed,2]];

end;

if a[s[open,1],s[open,2]]='m' then break;

if (s[closed,3]<>3)and(s[closed,1]>1)and(a[s[closed,1]-1,s[closed,2]]<>'o') then begin

inc(open);

s[open,1]:=s[closed,1]-1;

s[open,2]:=s[closed,2];

s[open,3]:=1;

s[open,4]:=s[closed,4]+b[s[closed,1],s[closed,2]];

end;

if a[s[open,1],s[open,2]]='m' then break;

if (s[closed,3]<>0)and(s[closed,2]>1)and(a[s[closed,1],s[closed,2]-1]<>'o') then begin

inc(open);

s[open,1]:=s[closed,1];

s[open,2]:=s[closed,2]-1;

s[open,3]:=2;

s[open,4]:=s[closed,4]+b[s[closed,1],s[closed,2]];

end;

if a[s[open,1],s[open,2]]='m' then break;

if (s[closed,3]<>2)and(s[closed,2]<y)and(a[s[closed,1],s[closed,2]+1]<>'o') then begin

inc(open);

s[open,1]:=s[closed,1];

s[open,2]:=s[closed,2]+1;

s[open,3]:=0;

s[open,4]:=s[closed,4]+b[s[closed,1],s[closed,2]];

end;

if a[s[open,1],s[open,2]]='m' then break;

end;

until (a[s[open,1],s[open,2]]='m')or(closed=open);

if q>s[open,4] then q:=s[open,4];

until (closed=open);

if q>=t then write('55555')

else

write(q);

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: