Exercise(17):装水管

来源:互联网 发布:物理原创课件 源码 编辑:程序博客网 时间:2024/04/27 19:23
/*        让我们一起装水管吧!    问题描述:    一块矩形土地被分为N*M的单位正方形,现在土地上已经设有一些水管,    水管将从坐标为(1,1)的矩形土地左上角左部边缘,延伸到坐标为(N,M)的    矩形土地的右下角右部边缘,(即左上角的单位正方形的左边为进水口,右下角的单位正方形的右边为出水口)。水管只有两种 L型和I型水管。每种管道将占据一个单位正方形土地。你现在可以旋转这些管道,使其构成一个管道系统,即创造出一条从    (1,1)到(N*M)的连通管道。注意,这块矩形土地内可能会有树木阻挡你放置管道。    L型水管有4种放置方法, I型水管有两种放置方法.    分别表示如下:    ^   —> <—   ^ ^     |   |     |   | | < —>  树木用0表示    —> v     v <— v     1   2   3   4  5   6    输入描述 InputDescription        第一行输入两个整数N,M (0<N,M<=50),用空格分隔开。表示将土地划分为N*M个单   位正方形。        剩下N行,每行有M个数,行内的数用空格隔开,行间要换行。表示各个单位        正方形土地的情况(水管or树木)。    输出描述 OutDescription        输出水管的连通方式,格式为(i,j) (0<i<=50,0<j<=50)        若无法形成一个连通系统则输出 impossible 。     样例输入 SampleInput        5 4        5 3 5 3        1 5 3 0        2 3 5 1        6 1 1 5        1 5 5 4    样例输出 SampleOutput        (1,1) (1,2) (2,2) (3,2) (3,3) (3,4) (4,4) (5,4)*/#include <iostream>using namespace std;int map[51][51];            // map 地图 bool mark[51][51];          // 标记 int n,m,top;                // n行 m列 top栈顶 bool flag;                  // 判断是否存在可连通的系统 typedef struct              // 用于储存结果 {    int x;                  // 横坐标     int y;                  // 纵坐标 } no, nodeList[2501];       // 栈nodeList    nodeList node;// 广搜 void DFS(int x,int y,int front)     // front为进水口 1,2,3,4分别表示左上右下 {    if(x==n && y==m+1)              // 判断是否找到出水口     {        flag = true;                // 标记连通系统已完成         for(int i=1;i<=top;i++)     // 输出各管道路径             cout<<"("<<node[i].x<<","<<node[i].y<<")"<<ends;        return;    }    if(x<1 || x>n || y<1 || y>m)    // 判断坐标是否越界         return;    if(mark[x][y])                  // 判断该水管是否已被使用         return;    mark[x][y] = true;              // 将该水管标记为已使用     node[++top].x = x;              // 将当前水管坐标存入栈     node[top].y = y;    if(map[x][y]>=1 && map[x][y]<=4)        // L型水管有4种摆放方式(1~4)     {        switch(front)        {            case 1:                         // 当进水口在左边 (L型水管对应的摆放方式有3、4)                DFS(x+1,y,2);               // 方式3:向下搜,向下后进水口改为上                 DFS(x-1,y,4);               // 方式4:向上搜,向上后进水口改为下                 break;            case 2:                         // 当进水口在上边 (L型水管对应的摆放方式有1、4)                DFS(x,y+1,1);               // 方式1:向右搜,向右后进水口改为左                 DFS(x,y-1,3);               // 方式4:向左搜,向左后进水口改为右                                            break;            case 3:                         // 当进水口在右边 (L型水管对应的摆放方式有1、2)                DFS(x-1,y,4);               // 方式1:向上搜,向上后进水口改为下                 DFS(x+1,y,2);               // 方式2:向下搜,向下后进水口改为上                 break;            case 4:                         // 当进水口在下边 (L型水管对应的摆放方式有2、3)                DFS(x,y+1,1);               // 方式2:向右搜,向右后进水口改为左                 DFS(x,y-1,3);               // 方式3:向左搜,向左后进水口改为右                 break;                      }    }    else if(map[x][y]>=5 && map[x][y]<=6)   // I型水管有2种摆放方式(5~6)    {        switch(front)        {            case 1:                         // 当进水口在左边 (I型水管对应的摆放方式有5)                DFS(x,y+1,1);               // 方式5:向右搜,向右后进水口仍为左                        break;            case 2:                         // 当进水口在上边 (I型水管对应的摆放方式有6)                DFS(x+1,y,2);               // 方式6:向下搜,向下后进水口仍为上                 break;            case 3:                         // 当进水口在右边 (I型水管对应的摆放方式有5)                DFS(x,y-1,3);               // 方式5:向左搜,向左后进水口仍为右                 break;            case 4:                         // 当进水口在下边 (I型水管对应的摆放方式有6)                DFS(x,y+1,4);               // 方式6:向上搜,向上后进水口仍为上                 break;        }    }    mark[x][y] = 0;                         // 该点尝试过后,取消标记     return;}int main(){    int i,j;    cin>>n>>m;                              // 输入表示 有n*m个单位正方形     if(n<=0 || n>50) return -1;    if(m<=0 || m>50) return -1;    for(i=1;i<=n;i++)                       // 读入地图         for(j=1;j<=m;j++)            cin>>map[i][j];    top = 0;                                // 栈顶初始化为0     DFS(1,1,1);                             // 从(1,1)开始搜,定义一开始的进水口在左边     if(!flag)                               // 当前水管的设置不可能装成一个连通系统时输出 impossible         cout<<"impossible"<<endl;    return 0;}
0 0
原创粉丝点击