谜题(Puzzle,UVa227)(算法竞赛入门经典习题3-5)

题目:输入5*5的网格,其中有一个格子是空的,其余的格子各有一个字母。一共有4中指令:A、B、L、R,分别表示吧空格上、下、左、右的相邻字母移到空格中。输入初始网格(以Z结束)和指令序列(以数字0结束),输出完成指令后的网格。如果有非法指令,应输出“This puzzle has no configuration.”。

思路:本题的思路很直接,按照题目要求一步步来即可,难点在于一些格式问题和输入输出问题(在输入上有做参考)。

已通过vj测试!

#include<iostream>
#include<string.h>
using namespace std;
#define maxn 100
char s1[5][5];   //5×5字符矩阵
char s2[maxn];   //指令

void swap(char s1[5][5], int a, int b, int x, int y) //形参的二维字符数组写法
{
	s1[a][b] = s1[x][y];
	s1[x][y] = ' ';
}

int main()
{
	int count = 0;                    //输出计数
	int a = 0, b = 0;                 //空格的所在行列
	int x = 0, y = 0;                 //交换函数中的参数
	char ch;
	while (1)
	{
		int flag = 1;                 //判断是否非法指令
		for (int i = 0; i < 5; i++)   //矩阵输入
		{
			for (int j = 0; j < 5; j++)
			{
				ch = getchar();
				if (ch == '\n')
					ch = getchar();   //吃掉换行符
				s1[i][j] = ch;
				if (s1[0][0] == 'Z')  //Z结束输入
					return 0;
				if (s1[i][j] == ' ')  //找到空格坐标
				{
					a = i;
					b = j;
				}
			}
		}

		memset(s2, 0, sizeof(s2));    //循环前要更新,否则上一轮循环会保留,如果没有覆盖掉,可能会有问题
		ch = getchar();
		for (int k = 0;; k++)         //指令输入
		{
			s2[k] = ch;
			ch = getchar();
			if (ch == '0')
				break;
		}
		if (count == 0)                  //注意输出格式
			cout << "Puzzle #" << ++count << ":" << endl;
		else
			cout << endl << "Puzzle #" << ++count << ":" << endl;

		for (int k = 0; k < strlen(s2); k++) //进行指令的步骤
		{
			if (s2[k] == 'A')
			{
				if (a - 1 >= 0)
				{
					x = a - 1;
					y = b;
					swap(s1, a, b, x, y);
					a -= 1;
				}
				else
				{
					cout << "This puzzle has no final configuration." << endl;
					flag = 0;
					break;
				}

			}
			else if (s2[k] == 'B')
			{
				if (a + 1 <= 4)
				{
					x = a + 1;
					y = b;
					swap(s1, a, b, x, y);
					a += 1;
				}
				else
				{
					cout << "This puzzle has no final configuration." << endl;
					flag = 0;
					break;
				}

			}
			else if (s2[k] == 'L')
			{
				if (b - 1 >= 0)
				{
					x = a;
					y = b - 1;
					swap(s1, a, b, x, y);
					b -= 1;
				}
				else
				{
					cout << "This puzzle has no final configuration." << endl;
					flag = 0;
					break;
				}

			}
			else if (s2[k] == 'R')
			{
				if (b + 1 <= 4)
				{
					x = a;
					y = b + 1;
					swap(s1, a, b, x, y);
					b += 1;
				}
				else
				{
					cout << "This puzzle has no final configuration." << endl;
					flag = 0;
					break;
				}

			}
		}
		if (flag == 0)
			continue;

		for (int i = 0; i < 5; i++)   //输出结果,注意格式
			for (int j = 0; j < 5; j++)
			{
				if (j == 4)
					cout << s1[i][j] << endl;
				else
					cout << s1[i][j] << " ";
			}
	}

	return 0;
}

博主认为本题的坑点过多,要通过测试需要很多注意的地方,掌握一些技巧即可(在vj平台下有更多坑点详解参考)。

1、完成序列后的puzzle输出有格外要求,除第一个puzzle外后面的都要在前一行多一个换行。

2、尽量用ch=getchar()而不是getchar()避免多吃字符。

3、输入格式中如果空格在最后一行,请手动输入,不要复制粘贴。

4、读取Z终止前不要有换行。

望指正!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值