题目连接:https://vjudge.net/problem/UVA-232
题意:输入一个r行c列的网格,以0输入结束,黑格用‘*’表示,每个白格有一个字母。如果一个白格的左边相邻位置上或者上边相邻位置没有白格,则把他作为起始格。首先,把所有的起始格子,从左到右,从上到下,以1.2.3编号。最后输出所有横向单词,单词第一个字母是起始格,向左延伸到边界或者黑格。在输出竖向单词,第一个字母是起始格,向下延伸到边界或黑格。具体输入参加题目。
思路:先遍历一遍,把所有的起始格标号。然后在输出横向单词,这个不难,但在输出竖向时,注意起始单词是一行一行寻早的,这里我采用了一个数组标记的方法,来处理,注意格式起始数字用“%3d",注意回车和细节处理。
#include<bits/stdc++.h>
using namespace std;
char m[13][13];
int vis[13][13],v[13][13];//两个标记数组
int r,c;
int main()
{
int n=1;
while(cin>>r,r)
{
if(r==0)
return 0;
cin>>c;
int s=1;
memset(vis,0,sizeof(vis));
memset(m,'*',sizeof(m));
memset(v,0,sizeof(v));
for(int i=1;i<=r;i++)
cin>>(m[i]+1);
if(n>1)
cout<<endl;
cout<<"puzzle #"<<n++<<":"<<endl;
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
if((m[i-1][j]=='*'||m[i][j-1]=='*')&&m[i][j]!='*')
vis[i][j]=s++;
if(m[i][j]=='*')
vis[i][j]=-1;
if(m[i][j]!='*')
v[i][j]=1;//每个字母进行处理
}
}
cout<<"Across"<<endl;
for(int i=1;i<=r;i++)
{
int l,p;l=p=0;
for(int j=1;j<=c;j++)//早到起始格,直接把后面的输出。
{
if(vis[i][j]>0&&p==0)
{
printf("%3d.",vis[i][j]);
l=1;p=1;
}
if(m[i][j]!='*')
{
cout<<m[i][j];
}
if(m[i][j]=='*')
{
p=0;
if(l)cout<<endl;
l=0;
}
}
if(l)cout<<endl;
}
cout<<"Down"<<endl;
for(int i=1;i<=r;i++)
{
int l=0,p=0;
for(int j=1;j<=c;j++)
{
if(v[i][j]==1)
{
for(int k=i;k<=r;k++)//找到起始格,把竖着的输出,并进行标记,下一行,不在输出
{
if(v[k][j]==1&&p==0)
{
printf("%3d.",vis[k][j]);
p=1;
}
if(m[k][j]!='*')
{
cout<<m[k][j];
v[k][j]=0;
}
if(m[k][j]=='*')
{
break;
}
}
p=0;
cout<<endl;
}
}
}
//cout<<endl;
}
return 0;
}