雜談 程式設計解決水管工遊戲

2022-07-08 19:48:12 字數 2683 閱讀 2198

程式設計是一門極難上手的技能,僅僅憑著課堂上的知識,只能是熟悉一門程式語言的語法。但要是用計算機來解決一些實際的問題,哪怕是智力問題,課本上的知識是遠遠不夠的。

程式設計就像學游泳。學游泳一定要在水裡學,要在水裡摸索體會。學程式設計也是如此。

下面給大家帶來乙個有趣的小問題,希望大家能夠學習到其中的程式設計思維與方法,尤其是中間建立模型的過程,相當精彩,大家欣賞一下。

以下內容改編自《啊哈,演算法》第4章第6節

一塊矩形土地被分為n*m的單位正方形,這塊土地裡埋設一些水管,水管將從座標為(1,1)的矩形土地的左上角左部邊緣,延伸到座標為(n,m)的矩形土地的右下角右部邊緣。

水管只有兩種:

土地中還有障礙物(比如樹木等)

每種水管佔據乙個單位正方形土地。可以旋轉這些管道,使其構成乙個管道系統,創造一條從(1,1)到(n,m)的連通

管道。有障礙物的方格裡沒有管道。

我們用數字0表示障礙物,1到6表示管道的六種不同的擺放方式(如下表)。┗┏

┓┛━┃

1234

56於是,程式的輸入可以規定為:

第一行輸入矩形土地的大小n,m。

接下來輸入n行m列的數字,表示每個單位正方形土地中的管道情況(數字0表示障礙物,1到6表示管道)

樣例輸入為:

5 4

5 3 5 3

1 5 3 0

2 3 5 1

6 1 1 5

1 5 5 4

(自行腦補實際管道鋪設情況)

程式要輸出的是應該是鋪設的路徑,如果不存在這樣的路徑,則輸出impossible。

樣例輸出:

the path is:

(1,1) (1,2) (2,2) (3,2) (3,3) (3,4) (4,4) (5,4)

(注:鋪設管道的最左上角起點座標為(1,1),最右下角終點座標為(5,4),規定進水口在最左上角方格的左邊,出水口在最右下角方格的右邊,輸出路徑可能不唯一)

以下分析過程中的水管的圖形與土地的狀態請自行腦補

因為只有兩種水管,直管(2種狀態)和彎管(4種狀態)。首先從(1,1) 開始嘗試。(1,1)是直管,進水口又在

(1,1)的左邊,因此(1,1)處的水管只能用5號擺放方式。

之後達到(1,2)。(1,2)處是彎管,進水口在(1,2)的左邊,因此(1,2)有兩種排放方式,分別是3號與4號。由於4號

擺放方式會出界,只能用3號擺放方式,從而來到了(2,2)。

(2,2)處是直管,進水口在上方,只能用6號擺放方式,接下來,來到(3,2)。

(3,2)是彎管,進水口在上面,有2種擺放方式可以選擇,分別是1號和4號。

這兩種選擇都可以,我們就要分別去嘗試……

依次類推,直到來到(n,m+1)為止,方案產生。

這裡用到了深度優先搜尋dfs。當處在(x,y)處時,依次列舉當前管道的每一張擺放方式,但並非每一種都可以,還要

判斷(x,y)處的進水口的方向。

這裡規定進水口在左邊用數字1表示,在上邊用2表示,右邊用3表示,下邊用4表示。

要輸出路徑,只需要用乙個棧存放相應的結點就可以了。

#include 

#define max_n 55

#define max_m 55

int a[max_n][max_m], book[max_n][max_m];

int n, m, flag = 0;

struct node s[100];

int top = 0;

void dfs(int x, int y, int front) //x,y表示當前處理的位置座標,front表示(x,y)進水口的方法

//判斷是否越界

if (x < 1 || x > n || y < 1 || y > m)

return;

//判斷(x,y)處是否已經遍歷過

if (book[x][y] == 1)

return;

++top; s[top].x = x; s[top].y = y; //將當前座標壓棧

//當前水管是直管的情況

if (a[x][y] >= 5 && a[x][y] <= 6)

//當前水管是彎管的情況

if (a[x][y] >= 1 && a[x][y] <= 4)

//進水口在上邊

if (front == 2)

//進水口在右邊

if (front == 3)

//進水口在下邊

if (front == 4)

}book[x][y] = 0; //取消標記

top--; //將當前座標從棧中彈出

return;

}int main(void)

return

0;}

學習程式設計的過程其實是一種修煉,不斷挑戰難題,挑戰自己,才能不斷提公升自己的思維能力,鍛鍊自己的數理能力,

豐富自己的**能力和程式設計技巧。

這裡的水管工問題就是很有啟發性的例子。還有許多有趣的問題值得我們用計算機程式設計去解決,這樣我們可以從演算法思維的角度考察問題,獲得靈感。

這樣的問題有很多,推薦大家一本書《演算法趣題》,裡面收錄了很多有趣的問題,值得我們思考,並且在計算機上用**實現。

水管工遊戲

1 題目 水管工遊戲是指如下圖中的矩陣中,一共有兩種管道,乙個是直的,乙個是彎的,所有管道都可以自由旋轉,最終就是要連通入水口可出水口。其中的樹為障礙物。2 演算法思路 本題使用的是深度優先搜尋演算法,先標識入水口方向,在每次探索新管道的時候上根據入水口方向進行擴充套件,然後根據管道的型別來判斷下乙...

4 6水管工遊戲

include includeusing namespace std int a 51 51 假設徒弟的大小不超過50 50 int book 51 51 n,m,flag 0 struct notes 100 int top 0 void dfs int x,int y,int front 判斷這...

DFS 水管工遊戲

ac 今天來複習一下如何用dfs找到能使首尾連線的通道,並顯示出來。一塊矩形土地被分為n m的單位正方形,現在這塊土地上已經埋設有一些水管,水管將從座標為 1,1 的矩形土地的左上角座標邊緣,延伸到座標為 n,m 的矩形土地的右下角右部邊緣。水管有兩種,彎的和直的。每種管道將佔據乙個單位正方形土地。...