您的位置:首页 > 其它

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

2017-08-31 17:10 405 查看
题意:就是找每一个*区域中有多少个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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: