习题3-6 纵横字谜的答案(Crossword Answers, ACM/ICPC World Finals 1994, UVa232)

原题vjudge

输入一个rc列(1≤rc≤10)的网格,黑格用“*”表示,每个白格都填有一个字母。 如
果一个白格的左边相邻位置或者上边相邻位置没有白格(可能是黑格,也可能出了网格边
界),则称这个白格是一个起始格。
首先把所有起始格按照从上到下、 从左到右的顺序编号为
1, 2, 3,…,如图3-7所示。
3-7 rc列网格
接下来要找出所有横向单词(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;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值