UVa-657 The die is cast(dfs嵌套)

来源:互联网 发布:自己怎么找淘宝优惠券 编辑:程序博客网 时间:2024/06/12 02:22

题意:就是找每一个*区域中有多少个X区域,相连的条件是有公共边,公共点不算

分析:用两次dfs,dfs1用来搜索*区域,并把每一个*变为 . ,  在这个过程中如果碰到X,则执行dfs2,用来搜索与该X相连的其他X,并且把X变为*

这道题有一个细节就是,在dfs1中,必须先搜索X,在搜索*,看这样一个例子:

6 6                                          
......
..*X..
..*...
......
......
......

如果先搜索X,答案是1,正确;如果先搜索*,答案是0 1,错误

因为在搜索X时,搜索结束后,要搜索的坐标值仍是X的坐标值,此时X变为*,这时候正好继续搜索*,但是如果先搜索*在搜索X,那么X搜索结束后,会进行下一轮循环,此时要搜索的坐标值发生改变,那么刚刚那个由X变来的*就会被我们忽略过去了,比如像例子这种对角的情况。

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>using namespace std;char map[52][52];int r[52];int w, h;int sum;int M_num;void dfs1(int i, int j);void dfs2(int i, int j);void dfs1(int x, int y) {printf("dfs1:%d %d\n", x, y);map[x][y] = '.';for (int i = -1; i <= 1; i++)for (int j = -1; j <=1; j++) {if ((i == -1 && j == 1) || (i == 1 && j == -1) || (i == 1 && j == 1) || (i == -1 && j == -1)) continue;int x0 = x + i;int y0 = y + j;if (x0 >= 0 && x0 < h && y0 >= 0 && y0 < w){    if (map[x0][y0] == 'X') {           //这里要先搜索X    dfs2(x0, y0);    M_num++;    }    if (map[x0][y0] == '*'){    dfs1(x0, y0);}}}}void dfs2(int i, int j){printf("dfs2:%d %d\n", i, j);map[i][j] = '*';for(int p = -1; p<=1; p++){for(int q = -1; q<=1; q++){if(p == 1 && q == 1 || p == -1 && q == -1 || p == 1 && q == -1 || p == -1 && q == 1) continue;int nx = i+p, ny =j+q;if(nx>=0 && nx<h && ny>=0 && ny<w && map[nx][ny] == 'X'){dfs2(nx, ny);}}}}int main(){int T = 1;while(scanf("%d %d", &w, &h) == 2 && w){memset(r, 0, sizeof(r));memset(map, 0, sizeof(map));sum = 0;for(int i = 0; i<h; i++){scanf("%s", map[i]);}for(int i = 0; i<h; i++){for(int j = 0; j<w; j++){if(map[i][j] == '*') {M_num = 0;    dfs1(i, j);    r[sum] = M_num;    sum ++;    printf("cut!\n");}}}sort(r, r+sum);printf("Throw %d\n", T++);for(int i = 0; i<sum; i++){printf("%d", r[i]);printf(i == sum-1? "\n\n":" "); }}    return 0;} 


原创粉丝点击