1151. 魔板[Speical judge]
来源:互联网 发布:淘宝客推广在哪里展示 编辑:程序博客网 时间:2024/05/21 05:41
#include <iostream>#include <cstring> //include <string.h> #include <queue>using namespace std;int factorial[10];queue<int> q;struct Node{ char board[10]; //重点1:node下标代表康拓编码,board代表魔板状态 int step; //step 代表多少步转变 int vis; //vis代表是否存在模版状态 char record[100]; //record代表操作 }node[50000]; //重点2:由于使用了康托编码,空间 大大节省,最多有 8! 种情况 //生成 0到 8的阶乘数组void init_array() { int sum = 1; factorial[0] = 1; for (int i = 1; i <= 8; i++) { sum *= i; factorial[i] = sum; } }//重点3:康拓编码,获得魔板状态的康拓编码 int getId(char c[]) { bool used[10]; int id; memset(used, false, sizeof(used)); id = 0; for (int i = 0; i < 8; i ++) { for (int j = 1; j < c[i] - '0'; j ++) if (!used[j]) id += factorial[7 - i]; used[c[i] - '0'] = true; } return id;}//初始化node数组以及队列q的状态 void init() { init_array(); for (int i = 0; i < 50000; i ++) { node[i].vis = false; node[i].step = 0; node[i].record[0] = '\0'; } while (!q.empty()) q.pop();}void operate1(char temp[], int fa){ int idx; for (int i = 0; i < 4; i ++) //重点4:swap交换函数C语言 #include <string.h>或者#include <algorithm.h> swap(temp[i], temp[i + 4]); idx = getId(temp); if (!node[idx].vis) { strcpy(node[idx].board, temp); strcpy(node[idx].record, node[fa].record); node[idx].step = node[fa].step + 1; node[idx].record[node[idx].step - 1] = 'A'; node[idx].record[node[idx].step] = '\0'; node[idx].vis = true; q.push(idx); }}void operate2(char temp[], int fa){ int idx; char t1, t2; t1 = temp[3]; t2 = temp[7]; for (int i = 3; i >= 1; i --) { temp[i] = temp[i - 1]; temp[i + 4] = temp[i + 3]; } temp[0] = t1; temp[4] = t2; idx = getId(temp); if (!node[idx].vis) { strcpy(node[idx].board, temp); strcpy(node[idx].record, node[fa].record); node[idx].step = node[fa].step + 1; node[idx].record[node[idx].step - 1] = 'B'; node[idx].record[node[idx].step] = '\0'; node[idx].vis = true; q.push(idx); }}void operate3(char temp[], int fa){ int idx; char t; t = temp[1]; temp[1] = temp[5]; temp[5] = temp[6]; temp[6] = temp[2]; temp[2] = t; idx = getId(temp); if (!node[idx].vis) { strcpy(node[idx].board, temp); strcpy(node[idx].record, node[fa].record); node[idx].step = node[fa].step + 1; node[idx].record[node[idx].step - 1] = 'C'; node[idx].record[node[idx].step] = '\0'; node[idx].vis = true; q.push(idx); }}int main(){ init_array(); int N; char begin[10]; char goal[10]; char hold[10]; int idx; while(1) { cin >> N; if(N==-1) break; init(); //字符初始化 for (int i = 0; i < 4; i ++) begin[i] = (i + 1) + '0'; for (int i = 4; i < 8; i ++) begin[11 - i] = (i + 1) + '0'; begin[8] = '\0'; for (int i = 0; i < 8; i ++) cin >> goal[i]; goal[8] = '\0'; //获得begin字符串的康拓编码 idx = getId(begin); strcpy(node[idx].board,begin); node[idx].vis = true; //队列存储康拓编码 q.push(idx); while (!q.empty()) { idx = q.front(); //重:5:strcmp功能:比较字符串s1和s2。当s1<s2时,返回值<0;当s1=s2时,返回值=0;当s1>s2时,返回值>0 //属于C语言,因此需要#include <string.h> if (strcmp(node[idx].board, goal) == 0) { if (node[idx].step <= N) cout << node[idx].step<<" " << node[idx].record <<endl; //printf("%d %s\n", node[idx].step, node[idx].record); else cout << -1 <<endl; break; } //重点6:strcmp功能:复制字符串 //属于C语言,因此需要#include <string.h> strcpy(hold, node[idx].board); operate1(hold, idx); strcpy(hold, node[idx].board); operate2(hold, idx); strcpy(hold, node[idx].board); operate3(hold, idx); q.pop(); } } return 0;}