习题3-6 纵横字谜的答案(Crossword Answers, ACM/ICPC World Finals 1994, UVa232)
输入一个r行c列(1≤r,c≤10)的网格,黑格用“*”表示,每个白格都填有一个字母。
如
果一个白格的左边相邻位置或者上边相邻位置没有白格(可能是黑格,也可能出了网格边
界),则称这个白格是一个起始格。
首先把所有起始格按照从上到下、 从左到右的顺序编号为1, 2, 3,…,如图3-7所示。
图3-7 r行c列网格
接下来要找出所有横向单词(Across)。 这些单词必须从一个起始格开始,向右延伸到
一个黑格的左边或者整个网格的最右列。 最后找出所有竖向单词(Down)。 这些单词必须
从一个起始格开始,向下延伸到一个黑格的上边或者整个网格的最下行。 输入输出格式和样
例请参考原题
#include <bits/stdc++.h>
using namespace std;
char cA[10][10];//crowssword Answers
int r,c;
typedef pair<int,int> P;
P p1;
typedef struct{
P coordinate;
bool across;
bool down;
}ad;//起始点数组,记录当前点坐标以及能否横纵向输出单词
ad b[100];
int main()
{
//freopen("input.txt","r",stdin);
int kase=0;
while(~scanf("%d%d",&r,&c)&&r&&c){
getchar();
kase++;
if(kase>=2) printf("\n");
printf("puzzle #%d:\n",kase);
for(int i=0;i<100;i++){//初始化起始点数组;
b[i].across=false;
b[i].down=false;
}
char ca;
for(int i=0;i<r;i++){
int j=0;
while((ca=getchar())!='\n'&&j<c){//输入数据
cA[i][j]=ca;
j++;
}
}
/*for(int i=0;i<r;i++){
for(int j=0;j<c;j++){
printf("%c",cA[i][j]);
}
printf("\n");
}*/
int num=0;
for(int i=0;i<r;i++){//思路是遍历如果左边不是单词就能往右输出;上下同理;
for(int j=0;j<c;j++){
if(cA[i][j]=='*')continue;
if(i-1<0||cA[i-1][j]=='*'||j-1<0||cA[i][j-1]=='*'){
num++;
b[num].coordinate.first=i;
b[num].coordinate.second=j;
if(i-1<0||cA[i-1][j]=='*'){
b[num].down=true;
}
if(j-1<0||cA[i][j-1]=='*'){
b[num].across=true;
}
}
}
}
printf("Across\n");
//输出遍历了两遍数组分别输入横纵的单词
for(int i=1;i<=num;i++){
if(b[i].across==true){
printf("%3d.",i);
int x=b[i].coordinate.first;
int y=b[i].coordinate.second;
while(cA[x][y]!='*'&&y<c){
printf("%c",cA[x][y]);
y++;
}
printf("\n");
}
}
printf("Down\n");
for(int i=1;i<=num;i++){
if(b[i].down==true){
printf("%3d.",i);
int x=b[i].coordinate.first;
int y=b[i].coordinate.second;
while(cA[x][y]!='*'&&x<r){
printf("%c",cA[x][y]);
x++;
}
printf("\n");
}
}
}
return 0;
}
#include <iostream>
#include <string>
#include <cstring>
#define mem(x) memset(x,0,sizeof(x))
using namespace std;
int n,m;
string maze[11];
int flag[11][11]={0};
void fun(int y,int x,int direct)
{
if(direct == 1)
{
printf("%3d.",flag[y][x]);
for(int j = x;j<m&&maze[y][j]!='*';j++)
{
cout<<maze[y][j];
}
cout<<endl;
}
else
{
printf("%3d.",flag[y][x]);
for(int i = y;i<n&&maze[i][x]!='*';i++)
{
cout<<maze[i][x];
}
cout<<endl;
}
}
int main()
{
int kase=0;
while(cin>>n)
{
mem(flag);
if(n==0) break;
++kase;
if(kase!=1) cout<<endl;
cout<<"puzzle #"<<kase<<":"<<endl;
cin>>m;
for(int i=0;i<n;i++)
{
cin>>maze[i];
}
int tag = 0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(maze[i][j]!='*')
{
if(i-1<0)
flag[i][j]=++tag;
else if(maze[i-1][j]=='*')
flag[i][j]=++tag;
else if(j-1<0)
flag[i][j]=++tag;
else if(maze[i][j-1]=='*')
flag[i][j]=++tag;
}
}
}
cout<<"Across"<<endl;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(flag[i][j]!=0)
{
if(j-1<0||maze[i][j-1]=='*')
{
fun(i,j,1);
}
}
}
cout<<"Down"<<endl;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(flag[i][j]!=0)
{
if(i-1<0||maze[i-1][j]=='*')
{
fun(i,j,0);
}
}
}
}
return 0;
}