题目:输入一个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;
}