原题地址
https://vjudge.net/problem/UVA-232
题意:输入r行c列的网格,黑格用 ‘*’ 表示, 每个白格上都填有一个字母。如果一个白格的左邻或上邻位置没有白格(黑格或越界),则称该白格是一个起始格。 首先将所有起始格按照从上到下,从左到右的顺序编号1,2,3…… 接下来找出所有的横向单词(从一个无左邻的起始格开始,向右延伸至黑格或边界),再找出所有的纵向单词(从一个无上邻的起始格开始,向下延伸至白格或边界)。按要求输出这些单词。
解题思路
本题是《算法竞赛入门经典》的习题3-6,是比较基本的枚举题目。
遍历每个格子,首先判断是否满足起始格的要求,如果满足再将以其为开端的横向单词、纵向单词(分别无左邻、上邻)的位置存到across、down结构体数组中。最后控制输出格式。
值得注意的点:
依然和输入字符相关,由于scanf依次读入了row、col值,所以读完col后会多出来一个换行,必须用getchar()吞掉这个回车,不然会被当成数组元素读入。如果题目要求两个连续输入的输出之间有一个空行(Separate output for successive input puzzles by a blank line.)那么不要每个测试之后都多输出一个换行,而是在第一个以后的测试结果输出前打入一个空行,这样可以保证结束标志0后没有换行。结构体里存的是这个单词的起始坐标(二元)和终止坐标(一元,要么横着,要么竖着),直接vector存string也是可以的。小心输出格式,一位编号前输出2个空格,两位编号前输出1个空格。
AC代码
#include <iostream>
#include <stdio.h>
using namespace std;
typedef struct word
{
int num, si, sj, e;
}WORD;
char puzzle[
15][
15];
WORD across[
1000], down[
1000];
int a,b;
bool isEligible(
int i,
int j)
{
if (puzzle[i][j] ==
'*')
return false;
else if (!i || !j || puzzle[i-
1][j] ==
'*' || puzzle[i][j-
1] ==
'*')
return true;
return false;
}
int main()
{
int row, col, kase =
0;
while (~
scanf(
"%d", &row) && row)
{
scanf(
"%d", &col);
getchar();
kase++;
for (
int i =
0; i < row; ++i)
{
for (
int j =
0; j < col; ++j)
scanf(
"%c", &puzzle[i][j]);
getchar();
}
a = b =
0;
int begin_num =
0;
for (
int i =
0; i < row; ++i)
{
for (
int j =
0; j < col; ++j)
{
if (isEligible(i, j))
{
begin_num++;
int k;
if (!j || puzzle[i][j-
1] ==
'*')
{
k = j+
1;
while (k < col && puzzle[i][k] !=
'*')
k++;
across[a].num = begin_num;
across[a].si = i, across[a].sj = j;
across[a].e = k;
a++;
}
if (!i || puzzle[i-
1][j] ==
'*')
{
k = i+
1;
while (k < row && puzzle[k][j] !=
'*')
k++;
down[b].num = begin_num;
down[b].si = i, down[b].sj = j;
down[b].e = k;
b++;
}
}
}
}
if(kase >
1)
printf(
"\n");
printf(
"puzzle #%d:\n", kase);
int i,j,r,c,ending;
printf(
"Across\n");
for (i =
0; i<a; ++i)
{
if (across[i].num <
10)
printf(
" ");
else if (across[i].num <
100)
printf(
" ");
printf(
"%d.", across[i].num);
r = across[i].si;
ending = across[i].e;
for (j = across[i].sj; j < ending; ++j)
putchar(puzzle[r][j]);
printf(
"\n");
}
printf(
"Down\n");
for (i =
0; i<b; ++i)
{
if (down[i].num <
10)
printf(
" ");
else if (down[i].num <
100)
printf(
" ");
printf(
"%d.", down[i].num);
c = down[i].sj;
ending = down[i].e;
for (j = down[i].si; j < ending; ++j)
putchar(puzzle[j][c]);
printf(
"\n");
}
}
return 0;
}
转载请注明原文地址: https://ju.6miu.com/read-666351.html