UVA227 谜题 Puzzle 题解

题意翻译

有一个5*5的网格,其中恰好有一个格子是空的,其他格子各有一个字母。一共有4中指令:A,B,L,R,分别表示把空格上、下、左、右的相邻字母移到空格中。输入初始网格和指令序列(以数字0结束),输出指令执行完毕后的网格。如果有非法指令,应输出“This puzzle has no final configuration.”例如,左图中执行ARRBBL0后,效果如右图所示。

输入输出样例

输入 #1

TRGSJ
XDOKI
M VLN
WPABE
UQHCF
ARRBBL0
ABCDE
FGHIJ
KLMNO
PQRS
TUVWX
AAA
LLLL0
ABCDE
FGHIJ
KLMNO
PQRS
TUVWX
AAAAABBRRRLL0
Z

输出 #1

Puzzle #1:
T R G S J
X O K L I
M D V B N
W P   A E
U Q H C F

Puzzle #2:
  A B C D
F G H I E
K L M N J
P Q R S O
T U V W X

Puzzle #3:
This puzzle has no final configuration.

思路

这道题的思路很简单,输入网格,按照指令移动空格,再输出.难点是如何进行输入输出,还有输出格式.

输入中有空格,回车,不能用scanf输入,需要用getchar输入,但又有一个问题,回车也会被getchar吸收,我们需要分情况来单独吸收回车.

还有输出一个回车还是输出两个回车.

代码

#include <stdio.h>
#include <string.h>
// 网格
char str[6][6];
int main() {
	// 标记输出哪种结果
    int flag = 1;
	int x;
	int y;
	int count = 0;
	// 输入Z的时候退出
    while (1) {
		// 吸收多余回车
        if (count > 0) {		
			getchar();
		}
        // 重置字符串数组
		for (int i = 0; i < 5; i++) {
			memset(str[i], ' ', sizeof(char) * 6);
		}
		flag = 1;
        // 输入
		for (int i = 0; i < 5; i++) {
			int k = 0;
			for (;k < 5; k++) {
				char ch;
				ch = getchar();
				if (ch == 'Z') {
					return 0;
				}
                // getchar是读取下一字符,当前字符是回车,则读取下一字符
				if (ch == '\n')
					ch = getchar();
				str[i][k] = ch;	
			}
            // 找到空格
			for (k = 0; k < 5; k++) {
				if (str[i][k] == ' ') {
					x = i;
					y = k;		
				}				
			}
		}
		char cn[1005];
		int m = 0;
		char n,c;
        // 因为指令中可能有回车,使用getchar.因为使用的是getchar,所以需要把指令读取完再移动空格
		while ((n = getchar()) != EOF && n != '0') {
			cn[m++] = n;
		}		
		for (int j = 0; j < m; j++)
		{
			c = cn[j];
			if (c == 'A') {
				if (x - 1 < 0) {
					flag = 0;
					break;
				} else {
					str[x][y] = str[x - 1][y];
					x = x - 1;
					str[x][y] = ' ';
				}
			} else if (c == 'B') {
				if (x + 1 >= 5) {
					flag = 0;
					break;					
				} else {
					str[x][y] = str[x + 1][y];
					x = x + 1;
					str[x][y] = ' ';
				}
			} else if (c == 'L') {
				if (y - 1 < 0) {
					flag = 0;
					break;					
				} else {
					str[x][y] = str[x][y - 1];
					y = y - 1;
					str[x][y] = ' ';
				}
			} else if (c == 'R') {
				if (y + 1 >= 5) {
					flag = 0;
					break;					
				} else {
					str[x][y] = str[x][y + 1];
					y = y + 1;
					str[x][y] = ' ';
				}
			} else {
				continue;
			}
		}
        // 相邻两个答案需要有一个空行
		if (count != 0)
			printf("\n");		
		printf("Puzzle #%d:\n", ++count);		
		if (flag == 0) {
			printf("This puzzle has no final configuration.\n");			
		} else {
			for (int i = 0; i < 5; i++) {
				for (int j = 0; j < 4; j++) {
					printf("%c ", str[i][j]);
				}
                // 末尾不能用空格
				printf("%c\n", str[i][4]);
			}
		}
	}
	return 0;
}

总结

题目其实很简单,但是输入输出很难处理,写了2个多小时,参考了很多题解之后才勉强AC.需要注意输入输出的处理和输出格式的细节.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值