Slash Maze(uva 705)

4 篇文章 0 订阅

本题的亮点是dfs和‘\’ ‘/’的转化方法。我采用了比较普遍和简单的方法,使用九宫格,这样由于斜着走可以变成横着走和竖着走的组合形式,所以在移步遍历时只用考虑上下左右四个方向。

编程步骤可分为三步:

(1)输入:通过键盘输入‘\’ ‘/’,将‘\’转化为100 010 001 ,‘/’ 转化为 001 010 100,构造map数组。

(2)dfs:判断移动一步之后,是否超过了边界,由此筛出非封闭点,check标志位标记是否封闭;

               另外为了提高效率,还可以设置非封闭已遍历点,即与边界相通的点,逐步扩大边界范围;

               此处还有一个教训:开始把row写成x把col写成y,导致想成坐标,结果此处h和w的位置写反。。。。

(3)寻找Cycles数和最大长度:寻找未遍历且map值为0的点,进行dfs。

做完此题后受益匪浅啊。

代码码:

#include<iostream>
#include<stdio.h>
#include<string.h>//memset函数的头文件
using namespace std;
int w,h,length,check=1;//宽,高,围住的方块数,标志位
int num=0;//Maze数
int visit[250][250];//75*3=225
int map[250][250];//visit为访问数组,记录该方块是否被访问过;map为输入数组,记录0,1的位置
int Move[4][2]={1,0,-1,0,0,1,0,-1};//移动的方向,由于采用九宫格,只需考虑上下左右四个方向
void dfs(int row,int col,int &len){//dfs 开始把row写成x把col写成y,导致想成坐标
	int R,C;//R是行,C是列 
	for (int i=0;i<4;i++){
		R=row+Move[i][0];
		C=col+Move[i][1];
		if ((R>=0)&&(R<3*h)&&(C>=0)&&(C<3*w)){//开始把row写成x把col写成y,导致想成坐标,结果此处h和w的位置写反。。。。
			if (visit[R][C]==0&&map[R][C]==0){
				visit[R][C]=1;
				len++;
				dfs(R,C,len);
			}
		}
		else check=0;
	}
}
int main(){
	int cycles,max;
	while(scanf("%d%d",&w,&h)){
		max=0;
		if (w+h==0) break;//输入0 0时的结果:无输出
		memset(map,0,sizeof(map));memset(visit,0,sizeof(visit));//清空map和visit
		num++;
		for(int i=0;i<h;i++)//输入map
			for(int j=0;j<w;j++){
				char ch;cin>>ch;
				if (ch=='\\'){
					map[3*i][3*j]=1;map[3*i+1][3*j+1]=1;map[3*i+2][3*j+2]=1;
				}
				else if (ch=='/'){
					map[3*i][3*j+2]=1;map[3*i+1][3*j+1]=1;map[3*i+2][3*j]=1;
				}
			}
		cycles=0;
		for(int i=0;i<3*h;i++)
			for(int j=0;j<3*w;j++){
				length=1;//已知一点判断下一点
				if (visit[i][j]==0&&map[i][j]==0){
					visit[i][j]=1;check=1;dfs(i,j,length);  
					if (check==1){
						cycles++;
						if (length>max) max=length;
					}
				}
			}
			cout<<"Maze #"<<num<<":"<<endl;
			if (cycles>0) cout<<cycles<<" Cycles; the longest has length "<<max/3<<'.'<<endl;//注意格式
			else cout<<"There are no cycles."<<endl;
			cout<<endl;
	}
	return 0;}

ps:编程过程中查阅的一些资料:

(1)数组的存储方式。

PASCAL和C语言中,数组按行优先顺序存储。

FORTRAN语言中,数组按列优先顺序存储。

(2)输入那点儿事:

cin.get()是保留回车在输入流队列中的.而cin是丢弃回车的.
所以cin.get()在下一次输入之前需要把之前的回车符给弄掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值