sicily 1150. 简单魔板

1150. 简单魔板

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge

Description

魔板由8个大小相同方块组成,分别用涂上不同颜色,用18的数字表示。

其初始状态是

1 2 3 4

8 7 6 5

对魔板可进行三种基本操作:

A操作(上下行互换):

8 7 6 5

1 2 3 4

B操作(每次以行循环右移一个):

4 1 2 3

5 8 7 6

C操作(中间四小块顺时针转一格):

1 7 2 4

8 6 3 5

用上述三种基本操作,可将任一种状态装换成另一种状态。

Input

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

第一行步数N不超过10的整数),表示最多容许的步数。

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

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

Output

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

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

注意:如果不能达到,则M输出-1即可。

Sample Input

45 8 7 64 1 2 338 7 6 51 2 3 4-1

Sample Output

2 AB1 A

题目分析

求由初始状态变为给定状态需要几步
注意到初始状态为
1234
8765
题目输入的是结束状态,同时其要求解法是在给定步数内,
所以当入队列的状态的步数超过了,可以提前结束搜索,

#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>

std::vector<std::string> visited;

bool unvisited(std::string data) {
  std::vector<std::string>::iterator res = find(visited.begin(), visited.end(), data);
  return res == visited.end();
}

std::string change(std::string init, char c) {
  std::string str = "";
  if (c == 'A')
    str = str + init[4] + init[5] + init[6] + init[7] + init[0] + init[1] + init[2] + init[3];
  else if (c == 'B')
    str = str + init[3] + init[0] + init[1] + init[2] + init[7] + init[4] + init[5] + init[6];
  else
    str = str + init[0] + init[5] + init[1] + init[3] + init[4] + init[6] + init[2] + init[7];
  return str;
}

int main()
{
  int steps;
  std::string init = "12348765";
  char c;
  while (scanf("%d", &steps)) {
    if (steps == -1)
      break;
    int ans;
    std::string target = "";
    for (int i = 0; i < 8; ++i) {
      scanf("%d", &ans);
      c = '1' + ans - 1;
      target = target + c;
    }
    if (init == target) {
      if (0 >= steps)
        printf("0\n");
      else
        printf("-1\n");
      continue;
    }
    if (!visited.empty())
      visited.clear();

    std::queue<std::string> q;
    std::queue<std::string> path;
    q.push(init);
    path.push("");
    visited.push_back(init);
    std::string sol = "";
    bool flag = true;
    while (!q.empty() && flag) {
      std::string state = q.front();
      q.pop();
      std::string nowpath = path.front();
      path.pop();

      std::string newstate;
      std::string newpath;
      for (int i = 0; i < 3; ++i) {
        c = 'A' + i;
        newstate = change(state, c);
        newpath = nowpath + (c);
        if (newpath.length() > steps) {
          flag = false;
          break;
        }
        if (newstate == target) {
          sol = newpath;
          flag = false;
          break;
        }
        if (unvisited(newstate)) {
//std::cout << newstate << std::endl;
          q.push(newstate);
          path.push(newpath);
          visited.push_back(newstate);
        }
      }
    }
    if (sol.length() <= steps && !flag)
      std::cout << sol.length() << " " << sol << std::endl;
    else
      printf("-1\n");
  }
}


你可能感兴趣的:(sicily 1150. 简单魔板)