UVA 657 掷骰子

题目大意:

通过图像识别的方式解读玩家的骰子的点数,

图像像素由三部分组成,背景像素'.',骰子像素'*',点数像素'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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值