[UVA232]Crossword Answers

本文分享了解决CROSSWORD问题的策略和代码实现经验,包括输入输出规范、简化输出复杂度的方法以及遍历和排序技巧。通过实例展示了如何高效解决该类型问题。

吸取了上一次的经验,这道题一共提交了两次得到AC(好开心,第一次这么少的次数就A了)。
注意事项:
1.输入上,这次非常的严格。输出上还是严格的按照要求来, 比如最后没有另外的空行啊, 序号的输出可以用%3d来输出(没尝试过其他的,scanf(“%3dxxxx”)通过了)。

技巧:
1.在CROSSWORD的后面一列和最下面一列用’*’填充,来简化输出的复杂度。
2.虽然题目要求排序,但是不一定要读出来每个单词之后排序,鉴于题目的数据量很小(10×10),可以遍历每个格子,因为序号是自左向右自上而下排列的,所以只要按照这个顺序遍历即可。

最后附上代码。

#include <stdio.h>

int main(void)
{
    int puzzle_num[11][11] = { 0 };
    char puzzle[11][11];
    int count_puzzle, count_total, total_row, total_column, count_row, count_column, temp_row;
    count_puzzle = 0;
    while (scanf("%d", &total_row))
    {
        if (total_row == 0)
            break;
        scanf(" %d", &total_column);
        while (getchar() != '\n');
        if (count_puzzle++ != 0)
            printf("\n");
        printf("puzzle #%d:\n", count_puzzle);
        for (count_row = 0; count_row < total_row; count_row++)
        {
            gets(puzzle[count_row]);
            puzzle[count_row][total_column] = '*';
        }
        for (count_column = 0; count_column < total_column; count_column++)
            puzzle[total_row][count_column] = '*';
        for (count_total = 1, count_row = 0; count_row < total_row; count_row++)
            for (count_column = 0; count_column < total_column; count_column++)
                if (count_row - 1 < 0 || count_column - 1 < 0 || puzzle[count_row - 1][count_column] == '*' || puzzle[count_row][count_column - 1] == '*')
                    if (puzzle[count_row][count_column] != '*')
                        puzzle_num[count_row][count_column] = count_total++;
        printf("Across\n");
        for (count_row = 0; count_row < total_row; count_row++)
            for (count_column = 0; count_column < total_column; count_column++)
            {
                if (puzzle[count_row][count_column] == '*')
                    continue;
                printf("%3d.", puzzle_num[count_row][count_column]);
                while (puzzle[count_row][count_column] != '*')
                    printf("%c", puzzle[count_row][count_column++]);
                printf("\n");
            }
        printf("Down\n");
        for (count_row = 0; count_row < total_row; count_row++)
            for (count_column = 0; count_column < total_column; count_column++)
            {
                if (puzzle[count_row][count_column] == '*' || (count_row - 1 > -1 && puzzle[count_row - 1][count_column] != '*'))
                    continue;
                temp_row = count_row;
                printf("%3d.", puzzle_num[count_row][count_column]);
                while (puzzle[temp_row][count_column] != '*')
                    printf("%c", puzzle[temp_row++][count_column]);
                printf("\n");
            }
    }
    return 0;
}
04-24
<think>好的,用户现在在问关于UVA232编程问题的解决方案或解释。首先,我需要回忆一下UVA232的具体内容。UVA232题目通常是关于“纵横字谜”(Crossword Answers)的问题。题目要求生成一个数字网格,并根据行和列生成相应的单词列表。 首先,确认问题内容:UVA232要求处理一个字符网格,其中有效的起始格(即可以横向或纵向组成单词的起始位置)需要被编号,然后输出横向和纵向的单词列表。每个起始格的条件是左边或上边是边界或'#'符号,而当前位置是字母。 接下来,用户可能需要解决方案的具体步骤。通常,解决这个问题需要分为几个步骤:读取输入网格,确定每个格子的编号,生成横向和纵向的单词列表,并按顺序输出。需要注意输入输出的格式,比如编号的顺序是从左到右、从上到下,横向单词按起始编号升序排列,纵向也是如此。 然后,考虑可能的代码实现。使用二维数组存储网格,另一个二维数组存储每个格子的编号。遍历每个格子,检查是否为起始格,如果是,则分配一个递增的编号。接着,横向遍历每一行,提取连续的字母作为单词,遇到'#'或边界时分割。纵向同理,但需要按列遍历,逐行检查。 此外,需要处理输入输出格式,比如每个谜题之间的空行,但注意最后一个谜题后不应有空行。这可能容易出错,需要特别注意。 用户可能遇到的常见问题包括:编号错误、单词分割不正确、输出格式不符合要求等。例如,起始格的判断条件是否正确,是否考虑了边界情况,横向和纵向的遍历顺序是否正确,编号是否连续递增等。 最后,根据用户的问题,提供具体的代码示例和解释,确保代码结构清晰,注释到位。同时,提醒用户注意测试边界情况,例如全'#'的网格,或者只有一行或一列的情况。</think>### UVA232 Crossword Answers 问题解析 UVA232题目要求处理一个字符网格,生成满足条件的单词编号及横向(Across)、纵向(Down)的单词列表。以下是具体步骤与示例代码。 --- #### **问题核心逻辑** 1. **编号规则** 格子$(r,c)$是起始格的条件: - 当前字符为字母(非`#`) - **左侧**是边界或`#`(横向起始)**或** **上方**是边界或`#`(纵向起始) 2. **横向单词提取** 从左到右逐行扫描,遇到连续字母序列时记录起始编号和单词。 3. **纵向单词提取** 从上到下逐列扫描,同样记录起始编号和单词。 --- #### **代码实现(Python)** ```python def solve_crossword(grid): rows = len(grid) cols = len(grid[0]) numbers = [[0] * cols for _ in range(rows)] num = 1 # 步骤1:分配编号 for r in range(rows): for c in range(cols): if grid[r][c] == '#': continue # 检查是否横向或纵向起始格 left_invalid = (c == 0) or (grid[r][c-1] == '#') top_invalid = (r == 0) or (grid[r-1][c] == '#') if left_invalid or top_invalid: numbers[r][c] = num num += 1 # 步骤2:提取横向单词 across = [] for r in range(rows): word = [] current_num = 0 for c in range(cols): if grid[r][c] == '#': if word: across.append((current_num, ''.join(word))) word = [] current_num = 0 else: if numbers[r][c] != 0 and current_num == 0: current_num = numbers[r][c] word.append(grid[r][c]) if word: # 行末剩余字母 across.append((current_num, ''.join(word))) # 步骤3:提取纵向单词 down = [] for c in range(cols): word = [] current_num = 0 for r in range(rows): if grid[r][c] == '#': if word: down.append((current_num, ''.join(word))) word = [] current_num = 0 else: if numbers[r][c] != 0 and current_num == 0: current_num = numbers[r][c] word.append(grid[r][c]) if word: down.append((current_num, ''.join(word))) return across, down ``` --- #### **关键注意事项** 1. **输入格式** 输入以`0 0`结束,每个谜题之间用空行分隔,但**最后一个谜题后无空行**。 2. **输出顺序** - 横向单词按编号升序排列 - 纵向单词按编号升序排列 3. **测试案例示例** 输入: ``` 2 2 A# #B 0 0 ``` 输出: ``` Puzzle #1: Across 1.A 3.B Down 1.A 2.B ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值