UVa-232 - Crossword Answers

该题与poj1888相似,连接为:http://poj.org/problem?id=1888

题意如下:

交叉字谜是一个很有趣的游戏。将地图分成一个个后挖空一些格子,剩下的格子中,连续的格子填入单词,由此填满整个地图。对于水平方向上连续的格子,自左至右填入一个单词,每个格子一个字母;竖直方向上的连续格子则是自上至下填入单词。现给每个单词分别编号,编号的规则如下。自左向右遍历一行,自上而下遍历所有行。对于每一个格子,若该格子为“水平序列”的首字母,或者是“竖直序列”的首字母,则给予编号,作为该单词的编号。若同时为两种序列的首字母,编号用同一个。其中,序列的定义为,序列方向上的前一个位置为空格子或地图外,后一个位置为空格子或地图外。现给定一个字谜游戏的答案,问按上述规则给每个格子进行编号后,两个方向上各个编号的单词分别是什么。
思路:模拟题。直接按编号规则扫描地图编号即可。扫描至某个字母时,若该字母为标记,则说明该字母为序列首部。此时,按特定方向扫描,直至遇到空格子或地图外位置,沿途的字母全部标记,说明这些字母都不是序列首。需要注意的是,“水平序列”与“竖直序列”是相对独立的。也就是说,一个字母即使是水平序列的中间元素,也有可能是竖直序列的首部。所以这里的标记数组我用了两个,分别记录两个方向上遍历情况。最后就是要注意一下输出格式

该题的代码为:

#include "stdio.h"
#include "string.h"
#define M 15

char s[M][M];
int r,c;
int pl[M][M],ph[M][M],mm[M][M];

int main()
{
    int i,j,k,t;
    int tc=1,ans;
    while(scanf("%d",&r)>0)
    {
        if(r==0) break;
        scanf("%d",&c);
        for(i=0;i<r;i++)
            scanf("%s",s[i]);
        printf("puzzle #%d:\n",tc++);
        memset(pl,0,sizeof(pl));
        memset(ph,0,sizeof(ph));
        memset(mm,0,sizeof(mm));
        ans=1;
        for(i=0;i<r;i++)
        {
            for(j=0;j<c;j++)
            {
                if(s[i][j]!='*')
                {
                    if(pl[i][j]==0)
                    {
                        mm[i][j]=ans;ans++;
                        k=j+1;
                        while(s[i][k]!='*'&&k<c)
                        {
                            pl[i][k]=1;
                            k++;
                        }
                    }
                    if(ph[i][j]==0)
                    {
                        if(mm[i][j]==0)
                        {
                            mm[i][j]=ans;
                            ans++;
                        }
                        k=i+1;
                        while(s[k][j]!='*'&&k<r)
                        {
                            ph[k][j]=1;
                            k++;
                        }
                    }
                }
            }
        }
        /*for(i=0;i<r;i++)
        {
            for(j=0;j<c;j++)
            {
                printf("%d ",mm[i][j]);
            }
            printf("\n");
        }*/
        printf("Across\n");
        for(i=0;i<r;i++)
            for(j=0;j<c;j++)
            {
                if(mm[i][j]&&!pl[i][j])
                {
                    printf("%3d.%c",mm[i][j],s[i][j]);
                    k=j+1;
                    while(pl[i][k])
                    {
                        printf("%c",s[i][k]);
                        k++;
                    }
                    printf("\n");
                }
            }
        printf("Down\n");
        for(i=0;i<r;i++)
            for(j=0;j<c;j++)
            {
                if(mm[i][j]&&!ph[i][j])
                {
                    printf("%3d.%c",mm[i][j],s[i][j]);
                    k=i+1;
                    while(ph[k][j])
                    {
                        printf("%c",s[k][j]);
                        k++;
                    }
                    printf("\n");
                }
            }
        printf("\n");
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值