加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

迷宫--小学生编程竞赛题目(两种解法,一种简单的推荐)

(2016-09-18 19:13:53)
标签:

小学生程序竞赛

c

迷宫

2014年第5题

分类: 其他

前两个月自己写了一个解法发到此博客里。今天把更简单的值得推荐的解法贴出来。一对比,就知道,当初我想得太复杂了。对于小学生学习编程而言,题目其实可以用更为简单的方式求解。

2016年9月18日写到:

(费了不少劲,写了几个版本,死了不少脑细胞。帮孩子做竞赛题目,我这个老妈也是蛮乒的。目前这个版本是最简单的,用了递归,貌似正确了。有喜欢的同学,可以用各种小于等于7*7的迷宫来测试一下。不知为何,这个网页貌似自动删除include后面的头文件,可能是尖括号的原因。一个头文件是fstream,一个头文件是string。)


试题 5 :迷宫(共 5 个测试点,每个点 4 分)

labyrinth.c / labyrinth.cpp / labyrinth.pas / labyrinth.bas

【问题描述】
  鹏鹏在一个迷宫里困住了。

迷宫是长方形的,有 n m 列个格子。一共有 3 类格子,空地用字符’.’ 表示,墙壁用’#’表示,陷阱用’*’表示。

特别地,迷宫中有两个特殊的格子:起点用’S’表示;终点用’E’表示。 起点和终点都是空地。(’S’和’E’均为大写字母)

  鹏鹏的任务是:从起点出发,沿着某条路径,走到终点。

游戏对路径的要求有三条:每次只能向相邻格子(上///右)移动一步; 不能经过墙壁(即可以经过空地和陷阱);不能走出迷宫边界。

聪明的你请告诉鹏鹏,他能完成任务吗?如果能,鹏鹏能否不经过任何陷阱 就完成任务呢?

【输入文件】
文件名:
labyrinth.in
文件中第一行为两个整数 n,m(2n,m7)。
接下来有
n 行,每行是一个长度为 m 的字符串,依次表示迷宫的每一行格子。

【输出文件】
文件名:
labyrinth.out
文件仅有一行,是一个字符串。 如果鹏鹏可以不经过任何陷阱就到达终点,输出”GOOD”;否则,如果经过

若干陷阱能到达终点,输出”OK”;否则,输出”BAD”。(所有字母均为大写)

【样例输入 1 34

   ##.E
   S*.#
   ...*

【样例输出 1 GOOD

【样例输入 2 33

##E S*. #..

【样例输出 2 OK

【样例解释】 ##67

1*5#
234*
样例 1 的最优路线为 1->2->3->4->5->6->7,如上图。 


2016年11月19日,今天推荐简单优选解法(孩子在听完老师讲解后完成的,思路来自与老师:))。9月18日的那个版本放在后面,做个对比。


#include 
#include
using namespace std;
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
char a[9][9];
int i,j,m,n;
bool flag,fl;
flag=true;
fl=false;
cin>>m;
cin>>n;
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
cin>>a[i][j];
if(a[i][j]=='S'){
a[i][j]='1';
}
}
}
while(flag){
flag=false;
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
if(a[i][j]=='1'){
//cout<<i<<" "<<j<<endl;
//cout<<a[i+1][j]<<" "<<a[i-1][j]<<" " <<a[i][j+1]<<" "<<a[i][j-1]<<endl;
if((a[i+1][j]=='E')||(a[i-1][j]=='E')||(a[i][j+1]=='E')||(a[i][j-1]=='E')){
cout<<"GOOD"<<endl;
return 0;
}
else if(a[i+1][j]=='.'){
a[i+1][j]='1';
flag=true;
}
else if(a[i-1][j]=='.'){
a[i-1][j]='1';
flag=true;
}
else if(a[i][j+1]=='.'){
a[i][j+1]='1';
flag=true;
}
else if(a[i][j-1]=='.'){
a[i][j-1]='1';
flag=true;
}
else{
}
}
}
}
}
flag=true;
while(flag){
flag=false;
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
if(a[i][j]=='1'){
if((a[i+1][j]=='E')||(a[i-1][j]=='E')||(a[i][j+1]=='E')||(a[i][j-1]=='E')){
cout<<"OK"<<endl;
return 0;
}
else if((a[i+1][j]=='.')||(a[i+1][j]=='*')){
a[i+1][j]='1';
flag=true;
}
else if((a[i-1][j]=='.')||(a[i-1][j]=='*')){
a[i-1][j]='1';
flag=true;
}
else if((a[i][j+1]=='.')||(a[i][j+1]=='*')){
a[i][j+1]='1';
flag=true;
}
else if((a[i][j-1]=='.')||(a[i][j-1]=='*')){
a[i][j-1]='1';
flag=true;
}
else{
}
}
}
}
}
cout<<"BAD"<<endl;
return 0;
}




(费了不少劲,写了几个版本,死了不少脑细胞。帮孩子做竞赛题目,我这个老妈也是蛮乒的。目前这个版本是最简单的,用了递归,貌似正确了。有喜欢的同学,可以用各种小于等于7*7的迷宫来测试一下。)

#include

#include

using namespace std;

ifstream cin("labyrinth.in");

ofstream cout("labyrinth.out");

int curhang,curlie,shang,slie,curdir,prehang,prelie;

char a[9][9];

int  b[9][9];

int flag = 0;

typedef struct{

int hang;

int lie;

}HISTRY;

HISTRY his[100];

int hisidx=0;

int stardisflag = 0;


#define DEBUGFLAG 1


int retrieve(int h,int l)

{

int i;

int cnt=0;

for (i=0;i<=hisidx;i++)

{

if ((his[i].hang == h)&&(his[i].lie == l))

cnt++;

}

return cnt;

}


int onestep(int curhang, int curlie, int nexthang, int nextlie, int dir)

{

#if 1//DEBUGFLAG==1

cout<<"cur:"<<curhang<<' '<<curlie<<"==>> "<<nexthang<<' '<<nextlie<<endl;

#endif

if ((prehang!=curhang)||(prelie!=curlie))

{

his[hisidx].hang=curhang;

his[hisidx++].lie=curlie;

prehang = curhang;

prelie = curlie; 

}

if ((flag == 2) || (retrieve(curhang,curlie) >= 10))

{

#if 1//DEBUGLFAG == 1

cout<<"h, l ="<<curhang<<" "<<curlie<<" "<<retrieve(curhang,curlie)<<"times"<<endl;

#endif

return 2;

}

if (a[nexthang][nextlie]=='E')

{

if (flag == 0)

return 0;

else 

{

stardisflag = 1;

#if DEBUGFLAG==1

cout<<"stardisflag    "<<stardisflag<<"======================"<<endl;

#endif

flag = 0;

if(onestep(shang,slie,shang,slie+1,0)==0)

return 0;

else

return 1;

}

}

if  ((a[nexthang][nextlie]=='.') && (b[curhang][curlie]!=((dir+2)%4)))

{

b[nexthang][nextlie]=dir;

return(onestep(nexthang,nextlie,nexthang,nextlie+1,0));

else if ((a[nexthang][nextlie]=='*') && (stardisflag == 0) && (b[curhang][curlie]!=((dir+2)%4)))

{

flag = 1;

b[nexthang][nextlie]=dir;

return(onestep(nexthang,nextlie,nexthang,nextlie+1,0));

}

else 

{

if ((a[nexthang][nextlie]=='*') && (stardisflag == 1))

a[nexthang][nextlie]=='#';

if (dir == 0)

{

if (b[curhang][curlie]!=3)

return(onestep(curhang,curlie,curhang+1,curlie,1));

else

return(onestep(curhang,curlie,curhang,curlie-1,2));

}

else if (dir == 1) 

{

if (b[curhang][curlie]!=0)

return(onestep(curhang,curlie,curhang,curlie-1,2));

else

return(onestep(curhang,curlie,curhang-1,curlie,3));

}

else if ((dir == 2) && (b[curhang][curlie]!=1))

return(onestep(curhang,curlie,curhang-1,curlie,3));

else

{

a[curhang][curlie]='#';

switch (b[curhang][curlie])

{

case 3:

return(onestep(curhang+1,curlie,curhang+1,curlie+1,0));

case 0:

return(onestep(curhang,curlie-1,curhang+1,curlie-1,1));

case 1:

return(onestep(curhang-1,curlie,curhang-1,curlie+1,0));

case 2:

return(onestep(curhang,curlie+1,curhang,curlie+2,0));

default:

flag = 2;

return 2;

}

}

}

    return 0;

}


int main(int argc,char**argv) {

int i,j,res;

int nn,m;

char x;

int  lpcnt=0; 

cin>>nn;

cin>>m;

cout<<"nn="<<nn<<" "<<"m="<<m<<endl; 

for (i=0;i<=nn+1;i++)

{

for (j=0;j<=m+1;j++)

a[i][j] = '#';

}

for (i=1;i<=nn;i++)

{

for (j=1;j<=m;j++)

cin>>a[i][j];

if (a[i][j] == 'S')

{

curhang = i;

curlie = j;

shang = i;

slie = j;

b[i][j] = 5;

}

}

}

res = onestep(curhang, curlie, curhang, curlie+1, 0);

if (res == 0)

cout << "GOOD" <<endl;

else if (res == 1)

cout << "OK" <<endl;

else

cout << "BAD" <<endl;

return(0); 








0

阅读 收藏 喜欢 打印举报/Report
前一篇:a few words
后一篇:self-awareness
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有