農場灌溉問題(回溯)
阿新 • • 發佈:2018-12-21
題目:
時限:1000ms 記憶體限制:10000K 總時限:3000ms
描述
一農場由圖所示的十一種小方塊組成,藍色線條為灌溉渠。若相鄰兩塊的灌溉渠相連則只需一口水井灌溉。
輸入
給出若干由字母表示的最大不超過50×50具體由(m,n)表示,的農場圖
輸出
程式設計求出最小需要打的井數。每個測例的輸出佔一行。當M=N=-1時結束程式。
輸入樣例
2 2 DK HF 3 3 ADC FJK IHE -1 -1
輸出樣例
2 3
提示
參考迷宮問題,實現時關鍵要解決好各塊的表示問題
思路:將每個塊轉化成左邊的形式,如果兩個塊的上下左右可以接在一起,就將兩個塊合併。
程式碼;
#include <iostream> using namespace std; struct node { char ch; int visit; int left,right,up,down; }maze[100][100]; int n,m; int dir[4][2] = {{1,0},{-1,0},{0,-1},{0,1}}; bool place(int x,int y,int nx,int ny) { if(nx > 0 && nx <= m && ny > 0 && ny <= n && !maze[nx][ny].visit) { if(nx == x && ny == y - 1 && maze[x][y].left && maze[nx][ny].right) return 1; if(nx == x && ny == y + 1 && maze[x][y].right && maze[nx][ny].left) return 1; if(nx == x - 1 && ny == y && maze[x][y].up && maze[nx][ny].down) return 1; if(nx == x + 1 && ny == y && maze[x][y].down && maze[nx][ny].up) return 1; } return 0; } void dfs(int x,int y) { maze[x][y].visit = 1; for(int i = 0;i < 4;i ++) { int nx = x + dir[i][0]; int ny = y + dir[i][1]; if(place(x,y,nx,ny)) dfs(nx,ny); } } int main() { while(cin >> m >> n && (m != -1 && n != -1)) { int cnt = 0; for(int i = 1;i <= m;i ++) { for(int j = 1;j <= n;j ++) { cin >> maze[i][j].ch; maze[i][j].visit = 0; maze[i][j].down = 0; maze[i][j].up = 0; maze[i][j].right = 0; maze[i][j].left = 0; if(maze[i][j].ch == 'A') maze[i][j].up = maze[i][j].left = 1; else if(maze[i][j].ch == 'B') maze[i][j].up = maze[i][j].right = 1; else if(maze[i][j].ch == 'C') maze[i][j].left = maze[i][j].down = 1; else if(maze[i][j].ch == 'D') maze[i][j].right = maze[i][j].down = 1; else if(maze[i][j].ch == 'E') maze[i][j].down = maze[i][j].up = 1; else if(maze[i][j].ch == 'F') maze[i][j].right = maze[i][j].left = 1; else if(maze[i][j].ch == 'G') maze[i][j].right = maze[i][j].left = maze[i][j].up = 1; else if(maze[i][j].ch == 'H') maze[i][j].up = maze[i][j].down = maze[i][j].left = 1; else if(maze[i][j].ch == 'I') maze[i][j].left = maze[i][j].right = maze[i][j].down = 1; else if(maze[i][j].ch == 'J') maze[i][j].up = maze[i][j].down = maze[i][j].right = 1; else if(maze[i][j].ch == 'K') maze[i][j].up = maze[i][j].down = maze[i][j].right = maze[i][j].left = 1; } } for(int i = 1;i <= m;i ++) { for(int j = 1;j <= n;j ++) { if(!maze[i][j].visit) { dfs(i,j); cnt ++; } } } cout << cnt << endl; } return 0; } /* 2 2 DK HF 3 3 ADC FJK IHE -1 -1 */