习题3-5 UVA227 Puzzle(50行AC代码)

紫书刷题进行中,题解系列点这里

习题3-5 UVA227 Puzzle(50行AC代码)

思路分析

给定一个5*5的字母拼图(A-X),包含一个空格,再给定移动序列,以0表示结束,求最终的拼图,若非法则输出相应提示信息。

读入拼图后,先找出空格位置,再根据移动序列移动即可。

注意点

  • 输入时getline可读入换行并丢弃它,cin遇到换行立即停止,不会丢弃,即下一个读取依旧是换行
  • 输出时两个puzzle间需有空行,最后一个puzzle不需要
  • 输入样例测试时,直接复制测试样例会导致第五列空格缺失,需自己补上

AC代码(C++11,简单模拟,复杂输入输出)

#include<bits/stdc++.h>
using namespace std;
string puzzle[5], s;
int cnt = 0, x, y, x2, y2, dict[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}}; // 上下左右偏移
map<char, int> mp{{'A',0}, {'B',1}, {'L',2}, {'R',3}}; // 字符映射到数字
bool isLegal = true, isOver = false; // 当前拼图是否有合法结果,是否结束
int main() {
    while(getline(cin,puzzle[0])) {
        if (puzzle[0][0] == 'Z') break;
        for (int i = 1; i < 5; i ++) getline(cin,puzzle[i]); // getline可读入空格
        for (int i = 0; i < 5; i ++) { // 找空格位置
            for (int j = 0; j < 5; j ++) { // 寻找空格坐标
                if(puzzle[i][j] == ' ') {
                    x = i; y = j;
                    break;
                }
            }
        }
        isOver = false; isLegal = true; // 初始化
        while(true) {
            cin >>s; getchar(); // 注意吸收换行
            for (auto ch : s) {
                if (ch == '0') { // 当前拼图结束
                    isOver = true; // 标记结束
                    if (cnt >= 1) printf("\n"); // 两个输出之间需有空行 
                    printf("Puzzle #%d:\n", ++cnt);
                    if (isLegal) { // 合法输出
                        for (int i = 0; i < 5; i ++) {
                            for (int j = 0; j < 5; j ++) {
                                printf("%c%c", puzzle[i][j], (j == 4) ? '\n' : ' ');
                            }
                        }
                    }
                    else printf("This puzzle has no final configuration.\n");
                }
                else {
                    x2 = x + dict[mp[ch]][0];
                    y2 = y + dict[mp[ch]][1];
                    if (x2 >= 0 && x2 < 5 && y2 >= 0 && y2 < 5) { // 是否合法
                        swap(puzzle[x][y], puzzle[x2][y2]); // 交换
                        x = x2; y = y2; // 更新x,y
                    }
                    else isLegal = false; // 非法
                }
            }
            if (isOver) break; // 跳出循环
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值