水管工游戏(随机地图版)
/*水管工游戏
一块快矩形的土地 被分成N*M的单位正方形 现在这个土地上已经买有一些水管
水管将从(1,1)的左上方 延伸到(N,M)d的矩形下方的右下角右部边缘
水管只有两种
"┛","━"
上方的外部方格代表单位正方形 内部的代表水管
每个水管占据一个单位正方形 你要做的就是旋转这些管道
使其可以连接成一个管道通路 即创造一条可以从(1,1)到(N,M)的连通管道
标有树木的方格代表这里没有管道 树木用▲表示
解:为了便于描述 我们用数字代表水管的状态
{"▲","┗","┎","┓","┛","━","┃"}
0 1 2 3 4 5 6 数字上方与图案对应
前四个为弯管的四种状态 后两个为直管的两种状态
EG:在另一个文件有图片 首先是(1,1) 假设其是直管 则只能用5号管子这种状态
其次为(1,2) 是弯管 进水口在左边 因此(1,2)的水管有两种方式 上面的第3种和第4种
先尝试3这种方法 之后到达 (2,2) (2,2)是直管只能是6这种方式。。。。
就这么尝试下去 直到(N,M+1)结束 便产生一种方案
所以用深度遍历的搜索方法来解决比较适合
我们来用上面的那六种 枚举一下
对于一个水管 如果是直管 则进水口在左边或右边只能用 5这种方式 如果是在上下两边则直接为6
而进水口是通过前一个水管来判断的 舍前一个水管为front
代码: dfs(int x,int y,int front)//x,y为当前格子的坐标
front 为进水口的方向1 2 3 4分别为 左 上 右 下
2
1 ✟ 3
4
当当前的水管为直管:
if(front==1) //进水口在左边
dfs(x,y+1,1)
if(front==2) //进水口在上边
dfs(x+1,y,2)
if(front==3) //进水口在右边
dfs(x,y-1,3)
if(front==4) //进水口在下边
dfs(x-1,y,4)
这个代码直接用 数组来表示会比较好 下面的代码会简化
当水管是弯管时
if(front==1) //进水口在左边
{
dfs(x+1,y,2) //3号的状态
dfs(x-1,y,4) //4号的状态
}
if(front==2) //进水口在左边
{
dfs(x,y+1,1) //1号的状态
dfs(x,y-1,3) //4号的状态
}
if(front==3) //进水口在左边
{
dfs(x-1,y,4) //1号的状态
dfs(x+1,y,2) //2号的状态
}
if(front==4) //进水口在左边
{
dfs(x,y+1,1) //2号的状态
dfs(x,y-1,3) //3号的状态
}
*/
下面是改进后的代码,挺好玩:
Windows版 C:
# include <stdio.h>
# include <stdlib.h>
# include <windows.h>
# include <time.h>
# define N 14 //地图的行数
# define M 16 //地图的列数
int Flag=0,BOOK[N+1][M+1]={0},S[N+2][M+2]={0},top=0,SUM=0,K,MAX[2];
const int NEXT[][2]={{0,0},{0,1},{1,0},{0,-1},{-1,0}};//用数组代替上面的判断
const int A[][3]={{0,0,0},{1,0,2},{0,1,1},{-1,0,4},{0,1,1}};//同上
const int B[][3]={{0,0,0},{-1,0,4},{0,-1,3},{1,0,2},{0,-1,3}};//同上
const char G[][3]={"▲","┗","┏","┓","┛","━","┃","进","出"};//数字对应的水管形状 或树木
const int T[][2]={{1,2},{4,3},{3,2},{4,1},{2,3},{1,4},{2,1},{3,4},{1,1},{3,3},{2,2},{4,4}};//弯的水管的进出方向1 2 3 4分别为 左 上 右 下
//const char Q[][3]={"┓","┓","┎","┎","┛","┛","┗","┗","━","━","┃","┃"};
const int LL[]={3,3,2,2,4,4,1,1,5,5,6,6};//可以用■ 代替上面的 G数组中的▲
char stack[M*N][3]={0}; //用二维数组模拟栈
void dfs(int X,int Y,int front);
int print(int num);
int main(){int i,j;do{printf("输出路径坐标请按1 否则按0:");scanf("%d",&K);while(getchar()!='\n');}while(K<0||K>1);do{S[1][0]=7;S[N][M+1]=8;printf("原水管分布图:");srand(time(NULL));//产生随机种子for(i=0;i<=N+1;i++) //输出地图{printf("\n");for(j=0;j<=M+1;j++){if(i&&j&&i!=N+1&&j!=M+1)S[i][j]=rand()%7;printf("%s",G[S[i][j]]);}}printf("\n");dfs(1,1,1); //深度遍历printf("当前地图%s能接通!\n",Flag?"\0":"不");if(Flag){printf("共%d种连接方式,已全显示 向上翻\n",SUM);printf("最大步数%d 是第%d种\n",MAX[0],MAX[1]);system("pause");}else{Sleep(1200);system("cls");}}while(!Flag);return 0;
}
int print(int num)
{int i;for(i=0;i<12;i++) // 2 // 1 3if(stack[num][2]==T[i][0]&&stack[num+1][2]==T[i][1])return LL[i]; //输出Q对应的水管形状return -1;
}
void dfs(int X,int Y,int front)
{int i,j;if(X==N&&Y==M+1)//如果方案找到 输出 信息{stack[top+1][2]=1;for(Flag=1;Flag<=top;Flag++) //输出路径坐标{if(K)printf("(%2d,%2d)\t",stack[Flag][0],stack[Flag][1]);S[stack[Flag][0]][stack[Flag][1]]=print(Flag);}printf("\n连接好之后[左上<入口>->右下<出口>]第%d种:\n共%d步\n",++SUM,top);if(top>=MAX[0]){MAX[0]=top;MAX[1]=SUM;}for(i=0;i<=N+1;i++){for(j=0;j<=M+1;j++)printf("%s",G[S[i][j]]);printf("\n");}return ;}if(X<1||Y<1||X>N||Y>M||BOOK[X][Y])return ;BOOK[X][Y]=1;stack[++top][0]=X;stack[top][1]=Y;if(S[X][Y]>=5&&S[X][Y]<=6){stack[top][2]=front;dfs(X+NEXT[front][0],Y+NEXT[front][1],front);//在上一个程序里有解释}if(S[X][Y]>=1&&S[X][Y]<=4){stack[top][2]=front;dfs(X+A[front][0],Y+A[front][1],A[front][2]);//在上一个程序里有解释dfs(X+B[front][0],Y+B[front][1],B[front][2]);}BOOK[X][Y]=0;//消除当前坐标的标记top--; //将当前坐标出栈return ;
}
手机的C4droid版本 TCC:
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <time.h>
# define N 14 //地图的行数
# define M 16 //地图的列数
int Flag=0,BOOK[N+1][M+1]={0},S[N+2][M+2]={0},top=0,SUM=0,K,MAX[2];
const int NEXT[][2]={{0,0},{0,1},{1,0},{0,-1},{-1,0}};//用数组代替上面的判断
const int A[][3]={{0,0,0},{1,0,2},{0,1,1},{-1,0,4},{0,1,1}};//同上
const int B[][3]={{0,0,0},{-1,0,4},{0,-1,3},{1,0,2},{0,-1,3}};//同上
const char G[][4]={"♡","┗","┏","┓","┛","━","┃","♡","♡"};//数字对应的水管形状 或树木
const int T[][2]={{1,2},{4,3},{3,2},{4,1},{2,3},{1,4},{2,1},{3,4},{1,1},{3,3},{2,2},{4,4}};//弯的水管的进出方向1 2 3 4分别为 左 上 右 下
//const char Q[][3]={"┓","┓","┎","┎","┛","┛","┗","┗","━","━","┃","┃"};
const int LL[]={3,3,2,2,4,4,1,1,5,5,6,6};//可以用■ 代替上面的 G数组中的■ ▲
char stack[M*N][3]={0}; //用二维数组模拟栈
void dfs(int X,int Y,int front);
int print(int num);
int main(){ int i,j; do{ printf("输出路径坐标请按1 否则按0:"); scanf("%d",&K); while(getchar()!='\n'); }while(K<0||K>1); do{ S[1][0]=7;S[N][M+1]=8; printf("原水管分布图:"); srand(time(NULL));//产生随机种子 for(i=0;i<=N+1;i++) //输出地图 { printf("\n"); for(j=0;j<=M+1;j++) { if(i&&j&&i!=N+1&&j!=M+1) S[i][j]=rand()%7; printf("%s",G[S[i][j]]); } } printf("\n"); dfs(1,1,1); //深度遍历 printf("当前地图%s能接通!\n",Flag?"\0":"不"); if(Flag) { printf("共%d种连接方式,已全显示 向上翻\n",SUM); printf("最大步数%d 是第%d种\n请按任意键继续……",MAX[0],MAX[1]); getchar();} else { sleep(1); system("clear"); } }while(!Flag); return 0;
}
int print(int num)
{ int i; for(i=0;i<12;i++) // 2 // 1 3 if(stack[num][2]==T[i][0]&&stack[num+1][2]==T[i][1]) return LL[i]; //输出Q对应的水管形状 return -1;
}
void dfs(int X,int Y,int front)
{ int i,j; if(X==N&&Y==M+1)//如果方案找到 输出 信息 { stack[top+1][2]=1; for(Flag=1;Flag<=top;Flag++) //输出路径坐标 { if(K) printf("(%2d,%2d)\t",stack[Flag][0],stack[Flag][1]); S[stack[Flag][0]][stack[Flag][1]]=print(Flag); } printf("\n连接好之后[左上<入口>->右下<出口>]第%d种:\n共%d步\n",++SUM,top); if(top>=MAX[0]) { MAX[0]=top; MAX[1]=SUM; } for(i=0;i<=N+1;i++) { for(j=0;j<=M+1;j++) printf("%s",G[S[i][j]]); printf("\n"); } return ; } if(X<1||Y<1||X>N||Y>M||BOOK[X][Y]) return ; BOOK[X][Y]=1; stack[++top][0]=X; stack[top][1]=Y; if(S[X][Y]>=5&&S[X][Y]<=6) { stack[top][2]=front; dfs(X+NEXT[front][0],Y+NEXT[front][1],front);//在上一个程序里有解释 } if(S[X][Y]>=1&&S[X][Y]<=4) { stack[top][2]=front; dfs(X+A[front][0],Y+A[front][1],A[front][2]);//在上一个程序里有解释 dfs(X+B[front][0],Y+B[front][1],B[front][2]); } BOOK[X][Y]=0;//消除当前坐标的标记 top--; //将当前坐标出栈 return ;
}
VM ubuntu 版 GCC
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <time.h>
# define N 14 //地图的行数
# define M 26 //地图的列数
int Flag=0,BOOK[N+1][M+1]={0},S[N+2][M+2]={0},top=0,SUM=0,K,MAX[2];
const int NEXT[][2]={{0,0},{0,1},{1,0},{0,-1},{-1,0}};//用数组代替上面的判断
const int A[][3]={{0,0,0},{1,0,2},{0,1,1},{-1,0,4},{0,1,1}};//同上
const int B[][3]={{0,0,0},{-1,0,4},{0,-1,3},{1,0,2},{0,-1,3}};//同上
const char G[][5]={"▲","┗","┏","┓","┛","━","┃","★","★"};//数字对应的水管形状 或树木
const int T[][2]={{1,2},{4,3},{3,2},{4,1},{2,3},{1,4},{2,1},{3,4},{1,1},{3,3},{2,2},{4,4}};//弯的水管的进出方向1 2 3 4分别为 左 上 右 下
//const char Q[][3]={"┓","┓","┎","┎","┛","┛","┗","┗","━","━","┃","┃"};
const int LL[]={3,3,2,2,4,4,1,1,5,5,6,6};//可以用■ 代替上面的 G数组中的▲
char stack[M*N][3]={0}; //用二维数组模拟栈
void dfs(int X,int Y,int front);
int print(int num);
int main(){ int i,j; do{ printf("输出路径坐标请按1 否则按0:"); scanf("%d",&K); while(getchar()!='\n'); }while(K<0||K>1); do{ S[1][0]=7;S[N][M+1]=8; printf("原水管分布图:"); srand(time(NULL));//产生随机种子 for(i=0;i<=N+1;i++) //输出地图 { printf("\n"); for(j=0;j<=M+1;j++) { if(i&&j&&i!=N+1&&j!=M+1) S[i][j]=rand()%7; printf("%s",G[S[i][j]]); } } printf("\n"); dfs(1,1,1); //深度遍历 printf("当前地图%s能接通!\n",Flag?"\0":"不"); if(Flag) { printf("共%d种连接方式,已全显示 向上翻\n",SUM); printf("最大步数%d 是第%d种\n",MAX[0],MAX[1]); //pause();getchar();} else { sleep(1); system("clear"); } }while(!Flag); return 0;
}
int print(int num)
{ int i; for(i=0;i<12;i++) // 2 // 1 3 if(stack[num][2]==T[i][0]&&stack[num+1][2]==T[i][1]) return LL[i]; //输出Q对应的水管形状 return -1;
}
void dfs(int X,int Y,int front)
{ int i,j; if(X==N&&Y==M+1)//如果方案找到 输出 信息 { stack[top+1][2]=1; for(Flag=1;Flag<=top;Flag++) //输出路径坐标 { if(K) printf("(%2d,%2d)\t",stack[Flag][0],stack[Flag][1]); S[stack[Flag][0]][stack[Flag][1]]=print(Flag); } printf("\n连接好之后[左上<入口>->右下<出口>]第%d种:\n共%d步\n",++SUM,top); if(top>=MAX[0]) { MAX[0]=top; MAX[1]=SUM; } for(i=0;i<=N+1;i++) { for(j=0;j<=M+1;j++) printf("%s",G[S[i][j]]); printf("\n"); } return ; } if(X<1||Y<1||X>N||Y>M||BOOK[X][Y]) return ; BOOK[X][Y]=1; stack[++top][0]=X; stack[top][1]=Y; if(S[X][Y]>=5&&S[X][Y]<=6) { stack[top][2]=front; dfs(X+NEXT[front][0],Y+NEXT[front][1],front);//在上一个程序里有解释 } if(S[X][Y]>=1&&S[X][Y]<=4) { stack[top][2]=front; dfs(X+A[front][0],Y+A[front][1],A[front][2]);//在上一个程序里有解释 dfs(X+B[front][0],Y+B[front][1],B[front][2]); } BOOK[X][Y]=0;//消除当前坐标的标记 top--; //将当前坐标出栈 return ;
}
水管工游戏(随机地图版)相关推荐
- 水管工游戏 (深搜)
水管工游戏 本题依然是采用搜索,深搜,广搜都可以,本代码采用深搜,此题在搜索时需要增加一些判断条件以及下一步要搜索的位置即可. 代码如下: #include<stdio.h> int a[ ...
- 水管工游戏——dfs
问题描述: 水管工游戏是指如下图中的矩阵中,一共有两种管道,一个是直的,一个是弯的,所有管道都可以自由旋转,最终就是要连通入水口可出水口.其中的树为障碍物. 方案: 输入格式:输入的第一行为两个整数N ...
- 啊哈算法之水管工游戏
先给不同状态的水管编给号吧 跟走迷宫一样的,深搜,每个dfs里遍历水管的状态,如果当前状态和水管指向的下一个状态能连通就深搜过去直到走到终点为止 上代码吧,这个代码是加强版,支持了更多的水管的编号,以 ...
- 深度搜索--水管工游戏
package com.xjj.Ah;import java.util.LinkedList;/*----深度搜索--水管工游戏----* 1. remove(),removeFirst():先移除在 ...
- android自定义水管流动,Android水管工游戏的简单脚本
Unity3d脚本Android水管工游戏的简单脚本 using UnityEngine; using System.Collections; public class TestGoto : Mono ...
- tianchai 12023 水管工游戏(DFS搜索)
题目描述(ID:12023) 标题: 水管工游戏 详情: 这小节有点难,看不太懂可以跳过哦. 最近小哼又迷上一个叫做水管工的游戏.游戏的大致规则是这样的.一块矩形土地被分为N*M的单位正方形,现在这块 ...
- 水管工游戏:dfs(递归)
添柴网这题好想不能评测,所以不确保代码的正确性 题目描述: 这小节有点难,看不太懂可以跳过哦. 最近小哼又迷上一个叫做水管工的游戏.游戏的大致规则是这样的.一块矩形土地被分为N * M的单位正方形,现 ...
- 搜索的实例——水管工游戏
这是一个用深搜解题的例子. [题目描述] 最近小哈又迷上一个叫水管工的游戏.游戏的大致规则是这样的.一块矩形的土地上被分为 n*m 的单位正方形,现在这块土地上已经埋有一些水管,水管将从坐标(1,1) ...
- 啊哈算法---水管工游戏
游戏大致规则是:一块矩形土地被分成N*M的单位正方形,现在这块土地已经埋设了一些水管. 水管将从矩形土地的左上角左部边缘,延伸到右下角右部边缘. 水管只有两种:弯管和直管 弯管有四种状态 直管有两种状 ...
最新文章
- java 毫秒转时间字符串_java 时间字符串 转换 毫秒
- 苹果智能车芯片已基本就绪!最新造车进展曝光,股价一夜暴涨4000亿
- Caffe学习系列(8):solver优化方法
- 2.1 为什么要进行实例探究-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
- 乐高计算机发展史教程,【乐高产品发展史特别篇】乐高恐龙发展史
- Element UI 总结
- Hub与Switch的帧的广播细节
- Google Bigtable文章终于出炉
- 14.看板方法---运营回顾
- 为什么不能线程调用类的成员函数_SLAM从0到1——13.SLAM中的多线程编程(2)
- Tomcat8+redis实现session共享
- 创建最基本的GD32F4xx的工程
- 普通进销存管理系统设计
- Excel-散点图(相关性及数据分布)分析
- OpenTK探索二:立体纹理贴图
- 第二天性-人类进化的经济起源
- java代码安全检测机制,下列选项中,属于Java语言的代码安全检测机制的一项是______。A.动态链接B.访问权限的检查C.通过接...
- 聚英国际|【燎原计划启动周第二期AMA】Filecoin经济模型及热点争议解读
- PHPExcel 操作
- webdriver自动化测试工具的使用,将chromedriver配置到path环境变量中,并测试是否成功