啊哈算法, 水管工游戏
游戏大致规则是:一块矩形土地被分成n*m的单位正方形,现在这块土地已经埋设了一些水管。
水管将从矩形土地的左上角左部边缘,延伸到右下角右部边缘。
水管只有两种:弯管和直管
弯管有四种状态
直管有两种状态
0表示树木,1,2,3,4表示弯管四种状态。5,6表示直管两种状态。
程序需要判断进水口:进水口在左边用1表示;在上边用2表示;在右边用3表示;在下边用4表示。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int n,m,flag=0, top=0;
int book[100][100], mp[100][100];
//使用栈存储路径
struct node
{
int x;
int y;
} stac[100];
//form表示进水口在哪边, 假设, 在左边是1,在上边是2,在右边是3,在下边是4
void dfs(int x, int y, int form)
{
if(x==n && y==m+1)
{
flag=1;
for(int i=1; i<=top; i++)
printf("{%d %d} ", stac[i].x, stac[i].y);
}
if(x<1 || x>n || y<1 || y>m)
return;
//不能重复使用同一个点, 如果该点在路径中已经使用过, 则这条方案不行
if(book[x][y]==1)
return;
book[x][y]=1;
top++;
//将当前尝试的点入栈
stac[top].x = x;
stac[top].y = y;
//直水管只有5和6两种水管
if(mp[x][y]>=5 && mp[x][y]<=6)
{
//进水口在左的情况
if(form==1)
dfs(x, y+1, 1); //5号水管状态, y+1表示本次出水口对下一个点的纵坐标的影响, 1表示本次出水口作为下一次入水口的方向
//进水口在上的情况
if(form==2)
dfs(x+1, y, 2);
//进水口在右的情况
if(form==3)
dfs(x, y-1, 3);
//进水口在下的情况
if(form==4)
dfs(x-1, y, 4);
}
//弯水管的情况有1,2,3,4种水管
if(mp[x][y]>=1 && mp[x][y]<=4)
{
//进水口在左的情况, 有3和4两种
if(form==1)
{
dfs(x+1, y, 2); //3
dfs(x-1, y, 4); //4
}
//进水口在上的情况, 有1和4两种
if(form==2)
{
dfs(x, y+1, 1);
dfs(x, y-1, 3);
}
//进水口在右的情况, 有1和2两种
if(form==3)
{
dfs(x-1, y, 4);
dfs(x+1, y, 2);
}
//进水口在下的情况, 有2和3两种
if(form==4)
{
dfs(x, y+1, 1);
dfs(x, y-1, 3);
}
}
book[x][y]=0;
//将当前尝试的点出栈
top--;
return;
}
int main()
{
top = 0;
int i,j;
memset(book, 0, sizeof(book));
memset(mp, 0, sizeof(mp));
scanf("%d %d", &n, &m);
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
scanf("%d", &mp[i][j]);
//初始坐标点及其入水口所在位置, 假设, 在左边是1,在上边是2,在右边是3,在下边是4
dfs(1,1,1);
if(flag==0)
{
printf("没有可用的方案\n");
}
return 0;
}