[sicily]1151. 魔板[Special judge]

Description

题目和A题相同,在这里我们把数据范围扩大:N可能超过10

请仔细考虑各种情况。
Input

输入包括多个要求解的魔板,每个魔板用三行描述。

第一行步数N,表示最多容许的步数。

第二、第三行表示目标状态,按照魔板的形状,颜色用18的表示。

当N等于-1的时候,表示输入结束。
Output

对于每一个要求解的魔板,输出一行。

首先是一个整数M,表示你找到解答所需要的步数。接着若干个空格之后,从第一步开始按顺序给出M步操作(每一步是ABC),相邻两个操作之间没有任何空格。

注意:如果不能达到,则M输出-1即可。
Sample Input
 Copy sample input to clipboard
45 8 7 64 1 2 338 7 6 51 2 3 4-1
Sample Output
2  AB1  A评分:M超过N或者给出的操作不正确均不能得分。

Problem Source: ZSUACM Team Member


#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>

using namespace std;

class MagicPad
{
public:
	vector<char> changeHistory;
	int magicPad[2][4];
	MagicPad()
	{
		magicPad[0][0] = 1;
		magicPad[0][1] = 2;
		magicPad[0][2] = 3;
		magicPad[0][3] = 4;
		magicPad[1][0] = 8;
		magicPad[1][1] = 7;
		magicPad[1][2] = 6;
		magicPad[1][3] = 5;
	}
	//上下行互换
	void opA()
	{
		int temp[4];
		for(int i = 0; i < 4; i++)
		{
			temp[i] = magicPad[0][i];
			magicPad[0][i] = magicPad[1][i];
			magicPad[1][i] = temp[i];
		}
		changeHistory.push_back('A');
	}
	//每次以行循环右移一个
	void opB()
	{
		int temp[4];
		int i;
		for(i = 0; i < 4; i++)
			temp[i] = magicPad[0][i];
		for(i = 1; i < 4; i++)
			magicPad[0][i] = temp[i-1];
		magicPad[0][0] = temp[3];

		for(i = 0; i < 4; i++)
			temp[i] = magicPad[1][i];
		for(i = 1; i < 4; i++)
			magicPad[1][i] = temp[i-1];
		magicPad[1][0] = temp[3];

		changeHistory.push_back('B');
	}
	//中间四小块顺时针转一格
	void opC()
	{
		int temp = magicPad[0][1];
		magicPad[0][1] = magicPad[1][1];
		magicPad[1][1] = magicPad[1][2];
		magicPad[1][2] = magicPad[0][2];
		magicPad[0][2] = temp;
		changeHistory.push_back('C');
	}

	bool checkEqual(int finalState[][4])
	{
		for (int i = 0; i < 2; i++)
			for (int j = 0; j < 4; j++)
				if (magicPad[i][j] != finalState[i][j])
					return false;
		return true;
	}
	int getIndex()
	{
		return 10000 * (magicPad[0][0] * 1000 + magicPad[0][1] * 100 + magicPad[0][2] * 10 + magicPad[0][3]) + (magicPad[1][0] * 1000 + magicPad[1][1] * 100 + magicPad[1][2] * 10 + magicPad[1][3]);
	}
};

int finalState[2][4];

int main()
{
	int maxStep;
	while(scanf("%d", &maxStep), maxStep!=-1)
	{
		for(int i = 0; i < 2; i++)
			for(int j = 0; j < 4; j++)
				scanf("%d", &finalState[i][j]);
		queue<MagicPad> state;
		state.push(MagicPad());
		
		map<int, bool> isVisit;

		bool succeed = false;
		while(!state.empty())
		{
			MagicPad current = state.front();
			if (current.changeHistory.size() > maxStep)
				state.pop();
			else if (current.checkEqual(finalState))
			{
				succeed = true;
				printf("%d ", current.changeHistory.size());
				for (int i = 0; i < current.changeHistory.size(); i++)
					printf("%c", current.changeHistory[i]);
				printf("\n");
				break;
			}
			else
			{
				state.pop();
				MagicPad next = current;
				next.opA();
				int index = next.getIndex();
				if (!isVisit[index])
				{
					state.push(next);
					isVisit[index] = true;
				}
				next = current;
				next.opB();
				index = next.getIndex();
				if (!isVisit[index])
				{
					state.push(next);
					isVisit[index] = true;
				}
				next = current;
				next.opC();
				index = next.getIndex();
				if (!isVisit[index])
				{
					state.push(next);
					isVisit[index] = true;
				}
			}
		}
		if (!succeed)
			printf("-1\n");
	}
	return 0;
}

感想:

一开始直接BFS, 直接超时了。

后来加入是否visited过的判断,由于用的是数组保存isVIsited难以判断大小,开得太大超内存,太小runTImeError

最后用map<int, bool>代替数组顺利通过

所以,当难以判断数组大小的时候,尽量用map来代替

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值