uva 657

本文介绍了一种用于识别骰子图案的算法实现。通过深度优先搜索(DFS)的方法,能够准确地识别出由字符组成的骰子图案中的各个面及其点数,并统计每个面的有效点数。文章详细解释了算法步骤,包括如何遍历骰子面和点数,以及如何正确处理边界条件。

哎,本来以为是一道简单题,但是WA了5,6次。。。这道题说给一个骰子的图,其中‘.’表示背景,‘*’表示是骰子的一个面,‘X’表示骰子面中的点。其中面和骰子的点都是4连接的,也就是说考虑上下左右四个方向。思路应该比较清晰:首先对骰子的面进行搜索,碰到面中的‘X’再对‘X’进行搜索。注意:对‘X’进行搜索时,需要注意‘X’不仅和相邻的‘X’是连接的,‘X’和相邻‘*’也是连接的(属于骰子的同一个面)。在我的代码中将搜索过的‘X’转换为尚未访问的‘*’,之后再对该点进行搜索。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string>
#include <string.h>
#include <algorithm>

using namespace std;
const int maxn = 50 + 20;
char dice[maxn][maxn];
int visitted[maxn][maxn];
int diceNum[maxn], diceBlocks;
int row, col, diretions[4][2] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, {1, 0} };
void dfsF(int r, int c);

bool inArea(int r, int c)
{
	if (r < 0 || r > row || c < 0 || c > col)
		return false;
	return true;
}

bool check(int r, int c)
{
	if (dice[r][c] == '*' || dice[r][c] == 'X')
		return true;
	return false;
}

void dfsS(int r, int c)
{
	if (inArea(r, c) && !visitted[r][c] && dice[r][c] == 'X')
	{
		visitted[r][c] = false;
		dice[r][c] = '*';
		for (int i = 0; i < 4; i++)
			dfsS(r + diretions[i][0], c + diretions[i][1]);
		/*for (int i = 0; i < 4; i++)
			dfsF(r + diretions[i][0], c + diretions[i][1]);*/
	}
}

void dfsF(int r, int c)
{
	if (inArea(r, c) && !visitted[r][c] && check(r, c))
	{
		visitted[r][c] = true;
		if (dice[r][c] == 'X')
		{
			visitted[r][c] = false;
			dfsS(r, c);
			diceNum[diceBlocks]++;
			dfsF(r, c);
		}
		else
		{
			for (int i = 0; i < 4; i++)
				dfsF(r + diretions[i][0], c + diretions[i][1]);
		}
	}
}

int main()
{
	freopen("in2.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
	int kaseNum = 0;
	while (cin >> col >> row)
	{
		memset(visitted, false, sizeof(visitted));
		memset(diceNum, 0, sizeof(diceNum));
		diceBlocks = 0;

		if (col <= 0 || row <= 0)
			break;
		for (int i = 0; i < row; i++)
			cin >> dice[i];

		for (int i = 0; i < row; i++)
		{
			for (int j = 0; j < col; j++)
			{
				if ('*' == dice[i][j] && !visitted[i][j])
				{
					dfsF(i, j);
					if (diceNum[diceBlocks] > 0 && diceNum[diceBlocks] <= 6)
						diceBlocks++;
				}
			}
		}//for int i

		sort(diceNum, diceNum + diceBlocks);
		cout << "Throw " << ++kaseNum << endl;
		for (int i = 0; i < diceBlocks - 1; i++)
			cout << diceNum[i] << " ";
		cout << diceNum[diceBlocks - 1] << endl << endl;
	}//while
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值