题目大意:
通过图像识别的方式解读玩家的骰子的点数,
图像像素由三部分组成,背景像素'.',骰子像素'*',点数像素'X'
根据投掷情况,解读图像中骰子点数,注意相邻为有边相接,且图像不一定是方形的
这个题目很不错,单纯的DFS没有办法读出点数,其中一种解法是先读出骰子图像,然后第二次进行DFS
但感觉略微麻烦,选择的办法是DFS,然后碰到'X'的时候采用BFS,将相邻的点数像素全部扫描到位,
这个过程中用队列记录同一幅投掷图中与点数相邻的其余骰子像素'*'
注意Output的格式
#include<iostream>
#include<cstdio>
#include<cstring>
#include<memory>
#include<queue>
#include<algorithm>
using namespace std;
///
int w, h;
char image[60][60]; //图像
bool vis[60][60]; //访问
int num[3000]; //结果
struct node{
int nrow;
int ncol;
};
queue<node> adjecent;
int k; //结果下标
int xd[] = { -1, 0, 1, 0};
int yd[] = { 0, 1, 0, -1};
bool bfs(int row,int col)
{
int i, j;
bool bRet = false;
vis[row][col] = true;
queue<node> qu;
node tempNode;
tempNode.nrow = row;
tempNode.ncol = col;
qu.push(tempNode);
while (!qu.empty())
{
tempNode = qu.front();
qu.pop();
node temp;
for (i = 0; i < 4; i++)
{
int addrow = tempNode.nrow + xd[i];
int addcol = tempNode.ncol + yd[i];
if (addrow <= h && addrow >= 1 && addcol <= w && addcol >= 1 && !vis[addrow][addcol])
{
if (image[addrow][addcol] == 'X')
{
temp.nrow = addrow;
temp.ncol = addcol;
qu.push(temp);
vis[addrow][addcol] = true;
}
//放入队列,返回以后对队列中元素进行DFS
else if (image[addrow][addcol] == '*')
{
bRet = true;
node node1;
node1.nrow = addrow;
node1.ncol = addcol;
adjecent.push(node1);
}
}
}
}
return bRet;
}
void dfs(int row, int col)
{
int i, j;
vis[row][col] = true;
for (i = 0; i < 4; i++)
{
int mrow = row + xd[i];
int mcol = col + yd[i];
if (mrow <= h && mrow >= 1 && mcol <= w && mcol >= 1 && !vis[mrow][mcol])
{
if (image[mrow][mcol] == '*')
{
dfs(mrow, mcol);
}
else if (image[mrow][mcol] == 'X')
{
num[k]++;
bool flag = bfs(mrow, mcol);
if (flag)//与点数像素相邻的有非点数的其它像素,DFS之
{
while (!adjecent.empty())
{
node node2;
node2 = adjecent.front();
adjecent.pop();
dfs(node2.nrow, node2.ncol);
}
}
}
}
}
}
int main()
{
///
int i, j;
int nCases = 1;
while (1)
{
cin >> w >> h;
if (w == 0)
break;
memset(image, 0, sizeof(image));
memset(vis, 0, sizeof(vis));
memset(num, 0, sizeof(num));
k = 0;
for (i = 1; i <= h; i++)
for (j = 1; j <= w; j++)
cin >> image[i][j];
for (i = 1; i <= h; i++)
{
for (j = 1; j <= w; j++)
{
if (!vis[i][j] && image[i][j] == '*')
{
while (!adjecent.empty())
adjecent.pop();
dfs(i, j);
k++;
}
}
}
sort(num, num + k);
cout << "Throw " << nCases << endl;
for (i = 0; i < k; i++)
{
if (i != k - 1)
cout << num[i] << " ";
else
cout << num[i];//注意输出格式
}
cout << endl << endl;
nCases++;
}
///
return 0;
}