题目
输入一个r行c列(1<=r, c<=10)的网格,黑格用 * 表示,每个白格都填有一个字母。
如果一个白格的左边相邻位置或者上边相邻位置没有白格(可能是黑格,也可能出了网格边界),
则称这个白格是一个起始格。
首先把所有起始格按照从上到下,从左到右的顺序编号为1,2,3,... ,如图
接下来要找出所有横向单词(Across)。这些单词必须从一个起始格开始,
向右延伸到一个黑格的左边或者整个网格的最右边列。最后找出所有的竖向单词(Down)。
这些单词必须从一个起始格开始,向下延伸到一个黑格的上边或者整个网格的最下行。
输入样例
2 2
AT
*O
6 7
AIM*DEN
*ME*ONE
UPON*TO
SO*ERIN
*SA*OR*
IES*DEA
0
样例输出
puzzle #1:
Across
1.AT
3.O
Down
1.A
2.TO
puzzle #2:
Across
1.AIM
4.DEN
7.ME
8.ONE
9.UPON
11.TO
12.SO
13.ERIN
15.SA
17.OR
18.IES
19.DEA
Down
1.A
2.IMPOSE
3.MEO
4.DO
5.ENTIRE
6.NEON
9.US
10.NE
14.ROD
16.AS
18.I
20.A
分析
用s[][] 存储r行c列的字符,lable[][]用来标记对应位置起始格的编号;
1.检测起始格
2.检测横向单词和竖向单词
c实现
#include<stdio.h>
#include<string.h>
#define maxn 12
int main(){
//r行,c列
int r,c;
while(scanf("%d",&r)&&r){
scanf("%d",&c);
char s[r][c];
//依次输入每行的数据
for(int i=0;i<r;i++)
{
scanf("%s",s[i]);
}
//用来标记起始格的序号1,2,...
int lable[r][c];
int count=0;
//检测标记对应位置的起始格
for(int i=0;i<r;i++){
for(int j=0;j<c;j++)
{
//起始格:首先不是黑格,然后为边界或者(左边相邻位置或者上边相邻位置没有白格)
if(s[i][j]!='*'&&(i==0||j==0||s[i-1][j]=='*'||s[i][j-1]=='*'))
{
lable[i][j] = (++count);
}else{
lable[i][j] = 0;//非起始格标记为0
}
}
}
//横向输出
printf("Across\n");
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
//横向单词满足的条件:首先该位置是起始格,然后左边界或左边相邻位置为黑格
if(lable[i][j]>0&&(j==0||s[i][j-1]=='*'))
{
printf("%d.%c",lable[i][j],s[i][j]);
for(int k=j+1;k<c;k++){
if(s[i][k]=='*'){
break;
}else{
printf("%c",s[i][k]);
}
}
printf("\n");
}
}
}
printf("Down\n");
for(int i=0;i<r;i++){
for(int j=0;j<c;j++){
//竖向单词满足的条件:首先该位置是起始格, 然后为上边界或者上边相邻位置为黑格
if(lable[i][j]>0&&(i==0||s[i-1][j]=='*'))
{
printf("%d.%c",lable[i][j],s[i][j]);
for(int k=i+1;k<r;k++){
if(s[k][j]=='*'){
break;
}else{
printf("%c",s[k][j]);
}
}
printf("\n");
}
}
}
}
return 0;
}