纵横字谜的答案(Crossword Answers,UVa232)(算法竞赛入门经典习题3-6) C++

题目:输入一个r行c列的网格,分为有黑白格,黑格用“*”表示,每个摆个填有一个字母。如果一个白格的左邻或者上邻位置没有白格,则称此白格是一个起始格。目标找出所有的横向单词(Across),从一个起始格开始,按从左到右的顺序延伸到黑格或者出边界为一个单词,再按从上到下的顺序依次一行寻找。找出所有竖向单词同理。具体输入输出格式请看原题。

思路:本题内容不难,只是代码过程较复杂,首先另开一个与crossword相同大小的二维数组来记录给起始格编号,这样可以方便输出的实现,然后就是根据题目要求调整条件,难在代码较麻烦,输出格式有些特殊要求。

关于如果做到找出单词,比如说横向的单词就去找第一个或者黑格后的作为起始,到末尾或者下一个黑格时终止,竖向的单词也是如此。

代码如下,已通过vj测试!

#include<bits/stdc++.h>
using namespace std;
char cw[100][100];
int id[100][100];

int main()
{
	int r, c;	//行数和列数
	int ch, count = 0;
	int k;
	while (cin >> r >> c && r!= 0)
	{
		k = 0;
		ch = getchar();	//吃掉多余的换行符
		memset(id, -1, sizeof(id));	//初始化id全为-1

		for (int i = 0; i < r; i++)	//初始化cross
		{
			for (int j = 0; j < c; j++)
			{
				ch = getchar();
				cw[i][j] = ch;
				if (cw[i][j] == '*')	//对黑格赋0
					id[i][j] = 0;
			}
			ch = getchar();
		}

		if (count == 0)
			cout << "puzzle #" << ++count << ":" << endl;
		else
			cout << endl << "puzzle #" << ++count << ":" << endl;

		for (int x = 0; x < r; x++)	//对cross编号
		{
			for (int y = 0; y < c; y++)
			{
				if ((x - 1 < 0 || y - 1 < 0 || (x - 1 >= 0 && y - 1 >= 0 && (cw[x - 1][y] == '*' || cw[x][y - 1] == '*'))) && cw[x][y] != '*')
					id[x][y] = (++k);
			}
		}

		//接下来是按要求输出
		cout << "Across" << endl;
		for (int x = 0; x < r; x++)	//Across的输出
		{
			for (int y = 0; y < c; y++)
			{
				if ((y - 1 < 0 && cw[x][y] != '*') || (y - 1 >= 0 && cw[x][y - 1] == '*' && cw[x][y] != '*')) //策略:判断是否在*右
					cout << setw(3) << id[x][y] << ".";
				if (cw[x][y] != '*')
					cout << cw[x][y];
				if (y + 1 < c && cw[x][y + 1] == '*' && cw[x][y] != '*')
					cout << endl;
				if (y + 1 == c && cw[x][y] != '*')
					cout << endl;
			}
		}

		cout << "Down" << endl;
		for (int x = 0; x < r; x++)	//Down的输出
		{
			for (int y = 0; y < c; y++)
			{
				if ((x - 1 < 0 && cw[x][y] != '*') || (x - 1 >= 0 && cw[x - 1][y] == '*' && cw[x][y] != '*')) //策略:判断是否在*下
				{
					cout << setw(3) << id[x][y] << ".";
					for (int p = x; p < r && cw[p][y] != '*'; p++)
					{
						cout << cw[p][y];
					}
					cout << endl;
				}
			}
		}
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值