[dfs] [FloodFill] POJ1970 The Game
分析题目:
map[20][20] 代表棋盘。
dr, dc是搜索时的每个方位的坐标变化。
win指示哪个棋胜利或者没有人胜利。
start_r , start_c指示胜利时最左或者竖连时最上的棋子坐标。
需要注意的是这段代码
1 if(inmap(pre_r, pre_c) && map[pre_r][pre_c]==map[r][c]) 2 continue;
通过这段代码可以确定该方向上的前一个格子里的棋子是否和当前格子里的棋子颜色相同,如果相同,那现在这个格子就不是该方向上最左或者竖连时最上的棋子,应该跳出该方向的循环。
解题代码:
1 #include <iostream> 2 using namespace std; 3 4 int map[20][20]; 5 int dr[4]={1,1,0,-1}; 6 int dc[4]={0,1,1,1}; 7 int win, start_r, start_c; 8 9 bool inmap(int r, int c) 10 { 11 if(r>=1 && r<=19 && c>=1 && c<=19) 12 return true; 13 else 14 return false; 15 } 16 17 void dfs(int r, int c) 18 { 19 for(int k=0; k<4; k++) 20 { 21 int temp_r = r, temp_c = c; 22 int count = 0; 23 int pre_r=temp_r-dr[k], pre_c=temp_c-dc[k]; 24 if(inmap(pre_r, pre_c) && map[pre_r][pre_c]==map[r][c]) 25 continue; //确保map[r][c]确实是最左或者竖连时候的最上的棋子 26 while(inmap(temp_r, temp_c) && map[temp_r][temp_c] == map[r][c]) 27 { 28 count++; 29 temp_r += dr[k]; 30 temp_c += dc[k]; 31 } 32 if(count == 5) 33 { 34 win = map[r][c]; 35 start_r = r; 36 start_c = c; 37 return; 38 } 39 40 } 41 42 return; 43 44 } 45 46 47 48 int main() 49 { 50 int t; 51 cin >> t; 52 while(t--) 53 { 54 for(int i=1; i<=19; i++) 55 for(int j=1; j<=19; j++) 56 cin >> map[i][j]; 57 58 win = 0; 59 60 for(i=1; i<=19; i++) 61 { 62 for(j=1; j<=19; j++) 63 { 64 if(map[i][j] == 0) 65 continue; 66 else 67 dfs(i, j); 68 } 69 } 70 71 cout << win << endl; 72 if(win != 0) 73 cout << start_r << " " << start_c << endl; 74 75 } 76 return 0; 77 }