算法竞赛入门经典(紫书)第三章——Crossword Answers UVA-232

14 篇文章 0 订阅

题意:
给一个 r 行 l 列的棋盘,每个格子中有字母或 ‘*’。
并告知存在特殊的格子,即最左边一列的字母格子、最上边一列的字母格子、左边或上边有 ‘*’ 格子的字母格子。
按照从左往右,从上往下的顺序对这些特殊格子进行编号就得到了题目给的图中的编号,即下图:

题目要求打印两组数据,一组是 Across,一组是 Down。
对于 Across 组,就是按照编号的顺序一行一行地找字符串,该字符串以编了号的字母为开始,向右延伸,直到遇到 ‘*’ 格子或行末。输出过的字母就不能再作为字符串开头了。
比如输出了 1、2、3 格子的字母,是以 1 号格子为开头的,2、3 号格子的字母已经输出过了,接下去就不用再以 2 号格子为开头或 3 号格子为开头找字符串了。

对于 Down 组,就是按照编号的顺序一列一列地找字符串,该字符串以编了号的字母为开始,向下延伸,直到遇到 ‘*’ 格子或行末。同 Across 组,输出过的字母就不能再作为字符串开头了。
此处,Down 组的按照编号的顺序这一要求需要强调一下,要使输出的编号从上往下是从小到大的。

思路:
1. 读取数据
2. 处理出编号
3. 输出 Across 组的数据,注意给输出过的字母打上标记
4. 输出 Down 组的数据,注意给输出过的字母打上标记

代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<utility>
#include<vector>
#include<cmath>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#include<sstream>
using namespace std;
typedef long long LL;


int r, l;
char ch[105][105];
int num[105][105];
bool flag[105][105];

int main()
{
    //freopen("in.txt", "r", stdin);
    int kase = 1;
    while(scanf("%d", &r)==1 && r!=0){
        scanf("%d", &l);
        if(kase != 1) printf("\n");
        printf("puzzle #%d:\n", kase++);

        for(int i=0; i<r; i++){
            scanf("%s", ch[i]);
        }

        //产生编号
        memset(num, 0, sizeof(num));
        int n = 1;
        for(int i=0; i<r; i++){
            for(int j=0; j<l; j++){
                if((i==0 || j==0) && ch[i][j]!='*'){
                    num[i][j] = n++;
                }else if((i>0&&ch[i-1][j]=='*' || j>0&&ch[i][j-1]=='*') && ch[i][j]!='*'){
                    num[i][j] = n++;
                }
            }
        }

        //输出 Across 组数据
        memset(flag, false, sizeof(flag));
        printf("Across\n");
        for(int i=0; i<r; i++){
            for(int j=0; j<l; j++){
                if(num[i][j]!=0 && !flag[i][j]){
                    printf("%3d.", num[i][j]);
                    int y = j;
                    while(y<l && ch[i][y]!='*') {
                        if(!flag[i][y]) flag[i][y] = true;
                        putchar(ch[i][y]);
                        y++;
                    }
                    printf("\n");
                }
            }
        }

        //输出 Down 组数据
        memset(flag, false, sizeof(flag));
        printf("Down\n");
        for(int i=0; i<r; i++){
            for(int j=0; j<l; j++){
                if(num[i][j]!=0 && !flag[i][j]){
                    printf("%3d.", num[i][j]);
                    int x = i;
                    while(x<r && ch[x][j]!='*') {
                        if(!flag[x][j]) flag[x][j] = true;
                        putchar(ch[x][j]);
                        x++;
                    }
                    printf("\n");
                }
            }
        }
    }
    return 0;
}

想看书上的源代码的话看这 (^▽^)
https://github.com/aoapc-book/aoapc-bac2nd

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值