Sicily 1151. 魔板

BFS（广搜）+ 康托展开 + Queue

1、BFS

I．   将初始状态放入队列，

II．  得到队列中的第一个状态，则从队列中pop

III． 得到pop出的状态与目标太进行比较，如果匹配则结束，否则对当前状态继续分别进行A、B、C三种操作，把得到的新状态依次放入队列。

IV．只要队列不为空，重复II操作。

2、康托展开

3、A、B、C操作的数学方法

A操作（结果存入m，n变量中）

after.x= curr.y;

after.y= curr.x;

B操作

after.x= after.x + curr.x[3]+curr.x[0]+curr.x[1]+curr.x[2];

after.y= after.y + curr.y[3]+curr.y[0]+curr.y[1]+curr.y[2];

C操作：

after.x = after.x +curr.x[0]+curr.y[1]+curr.x[1]+curr.x[3];

after.y = after.y +curr.y[0]+curr.y[2]+curr.x[2]+curr.y[3];

#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

struct Record{
string x,y;
string op;
}start,target;

const int PermSize = 8;
int factory[] = { 1, 1, 2, 6, 24, 120,720, 5040 }; // 7的阶乘（n-1的阶乘）
bool isVisited[50000];

void initial(){

string tmp = "";

// 初始化初态魔板
start.x = "1234";
start.y = "8765";
start.op = "";

target.x = "";
target.y = "";

for(int i = 0;i < 4;i++){
cin >> tmp;
target.x += tmp;
}
for(int j = 0;j < 4;j++){
cin >> tmp;
target.y += tmp;
}

memset(isVisited, false ,sizeof(isVisited));
}

int cantor( string buf )
{
int i, j, counted;
int result = 0;
for ( i = 0; i < PermSize; ++i )
{
counted = 0;
for( j = i + 1; j < PermSize + 1; ++j )
if( buf[i] > buf[j] )
++counted;
result = result + counted * factory[PermSize - i - 1];
}
return result;
}

bool isEqual(const Record &A,const Record &B){
return ( A.x == B.x && A.y == B.y );
}

Record operate(Record curr, Record after,int operation)
{
switch(operation){
case 0:
after.x = curr.y;
after.y = curr.x;
after.op += "A";
break;
case 1:
after.x = after.x + curr.x[3]+curr.x[0]+curr.x[1]+curr.x[2];
after.y = after.y + curr.y[3]+curr.y[0]+curr.y[1]+curr.y[2];
after.op += "B";
break;
case 2:
after.x = after.x + curr.x[0]+curr.y[1]+curr.x[1]+curr.x[3];
after.y = after.y + curr.y[0]+curr.y[2]+curr.x[2]+curr.y[3];
after.op += "C";
break;
}
return after;
}

// 广搜
void bfs( int m ){
if( isEqual(start,target) ){
cout << 0 << endl;
return;
}
queue<Record> records;
records.push(start);

// 队列不为空
while( !records.empty() ){
Record curr = records.front();
records.pop();

// 如果操作次数大于要求次数则返回-1
if( curr.op.size() > m ) {
cout << -1 << endl;
return;
}

// 当前态与目标太匹配则返回
if( isEqual(curr, target) ){
cout << curr.op.size() << " " << curr.op << endl;
return;
}

// 循环进行A,B,C操作
for( int i = 0; i < 3; i++ ){
Record after;
after.x = "";
after.y ="";
after.op = curr.op;

after = operate(curr,after,i);

int cn = cantor( after.x + after.y );
if( !isVisited[ cn ]){
isVisited[ cn ] = true;
records.push(after);
}
}
}
}

int main(){

int m;

while( cin >> m && m != -1 ){
initial();
bfs(m);
}

return 0;
}


sicily 1150 简单魔板

2011-06-14 14:15:00

[sicily]1151. 魔板

2015-10-11 14:54:29

1151魔板B

2016-03-09 22:47:08

Sicily 1150 简单魔板 && 1151 魔板 (BFS深度优先搜索+康托展开状态压缩)

2010-04-13 11:48:00

[Sicily 1150 1151 1515 魔板] BFS+判重（康托展开）

2015-04-26 16:53:41

Sicily 1151. 魔板解题报告

2012-10-30 09:51:31

[sicily online]1151. 魔板

2012-12-12 16:42:14

1151. 魔板

2014-10-23 19:12:15

Sicily 1151. 魔板[Speical judge]

2013-01-03 19:41:59

sicily 1150. 简单魔板 & 1151. 魔板

2012-10-28 14:06:45

Sicily 1151. 魔板