题目大意:就是看图中的骰子点数。
解题思路:两次深度遍历,第一次先找骰子,第二次在找点数,本来是用一个数组来记录这个地方是否访问过,但是后面发现这样对于两次的dfs会出现问题,所以就将访问过的X改成*,访问过的*改成点,这样就可以达到二次遍历。先找不是 .(点) 的字符,然后在这里面找X的块数,这个就是点数。
再次明确了,做题要细心。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N = 55;
int w, h, t = 0;
char G[N][N];
int dir[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
int answer[N * N], k;
void dfs(int x, int y) {
G[x][y] = '*';
for(int i = 0; i < 4; i++) {
int x1 = x + dir[i][0];
int y1 = y + dir[i][1];
if(x1 >= 0 && x1 < h && y1 >= 0 && y1 < w) {
if(G[x1][y1] == 'X')
dfs(x1, y1);
}
}
}
void handle(int x, int y) {
if(G[x][y] == 'X' ) {
dfs(x, y);
answer[k]++;
}
G[x][y] = '.';
for(int i = 0; i < 4; i++) {
int x1 = x + dir[i][0];
int y1 = y + dir[i][1];
if(x1 >= 0 && x1 < h && y1 >= 0 && y1 < w) {
if(G[x1][y1] != '.')
handle(x1, y1);
}
}
}
int main() {
while(scanf("%d%d%*c", &w, &h), w || h) {
t++;
memset(G, 0, sizeof(G));
memset(answer, 0, sizeof(answer));
int i, j;
for( i = 0; i < h; i++)
scanf("%s", G[i]);
k = 0;
for(i = 0; i < h; i++)
for(j = 0; j < w; j++) {
if(G[i][j] != '.') {
handle(i, j);
if(answer[k])
k++;
}
}
printf("Throw %d\n", t);
if(k == 0) {
printf("0\n\n");
continue;
}
sort(answer, answer + k );
for(i = 0; i < k ;i++) {
if(i != k - 1)
printf("%d ", answer[i]);
else
printf("%d\n\n", answer[i]);
}
}
return 0;
}