(提高课搜索完结撒花)
#include <bits/stdc++.h>
#define please return
#define Accept 0
#define orz ;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 100010;
int opp[10][10] = { // 手动打表出每一条链上的元素坐标
{0, 2, 6, 11, 15, 20, 22},
{1, 3, 8, 12, 17, 21, 23},
{10, 9, 8, 7, 6, 5, 4},
{19, 18, 17, 16, 15, 14, 13},
{23, 21, 17, 12, 8, 3, 1},
{22, 20, 15, 11, 6, 2, 0},
{13, 14, 15, 16, 17, 18, 19},
{4, 5, 6, 7, 8, 9, 10},
};
int sum[5]; // 求估值数组
int opposite[10] = {5, 4, 7, 6, 1, 0, 3, 2}; // 对应的操作
int q[100];
int path[100]; // 存每一次操作
int center[10] = {6, 7, 8, 11, 12, 15, 16, 17}; // 中间八个元素下标
int f() // 求估值函数(求法:贪心中的贪心,使劲贪)
{
memset(sum, 0, sizeof(sum));
for (int i = 0; i < 8; i ++) sum[q[center[i]]] ++;
int Max = 0;
for (int i = 1; i <= 3; i ++) Max = max(Max, sum[i]);
return 8 - Max;
}
void operation(int x) // 移动链
{
int t = q[opp[x][0]];
for (int i = 0; i < 6; i ++) q[opp[x][i]] = q[opp[x][i + 1]];
q[opp[x][6]] = t;
}
bool dfs(int depth, int max_depth, int last) // IDA*
{
if (depth + f() > max_depth) return false;
if (f() == 0) return true;
for (int i = 0; i < 8; i ++)
{
if (opposite[i] == last) continue;
operation(i);
path[depth] = i; // 记录操作
if (dfs(depth + 1, max_depth, i)) return true;
operation(opposite[i]); // 恢复现场
}
return false;
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
while (cin >> q[0], q[0])
{
for (int i = 1; i < 24; i ++) cin >> q[i];
int depth = 0;
while (!dfs(0, depth, -1)) depth ++;
if (depth == 0) cout << "No moves needed" << '\n';
else
{
for (int i = 0; i < depth; i ++) cout << (char)(path[i] + 'A');
cout << "\n";
}
cout << q[6] << '\n';
}
please Accept orz
}
绳!