程式設計是一門極難上手的技能,僅僅憑著課堂上的知識,只能是熟悉一門程式語言的語法。但要是用計算機來解決一些實際的問題,哪怕是智力問題,課本上的知識是遠遠不夠的。
程式設計就像學游泳。學游泳一定要在水裡學,要在水裡摸索體會。學程式設計也是如此。
下面給大家帶來乙個有趣的小問題,希望大家能夠學習到其中的程式設計思維與方法,尤其是中間建立模型的過程,相當精彩,大家欣賞一下。
以下內容改編自《啊哈,演算法》第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 的矩形土地的右下角右部邊緣。水管有兩種,彎的和直的。每種管道將佔據乙個單位正方形土地。...