在迭代加深的基础上,使用预估函数检查是否满足层数要求
180. 排书 - AcWing题库
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 15;
int n;
int q[N];
int w[5][N];
int f()
{
int tot = 0;
for(int i = 0; i + 1 < n; i ++ )
if(q[i + 1] != q[i] + 1)
tot ++;
return (tot + 2) / 3;
}
bool dfs(int depth, int max_depth)
{
if(depth + f() > max_depth) return false;
if(f() == 0) return true;
for(int len = 1; len <= n; len ++ )
for(int l = 0; l + len - 1 < n; l ++ )
{
int r = l + len - 1;
for(int k = r + 1; k < n; k ++ )
{
memcpy(w[depth], q, sizeof q);
int y = l;
for(int x = r + 1; x <= k; x ++, y ++ ) q[y] = w[depth][x];
for(int x = l; x <= r; x ++, y ++) q[y] = w[depth][x];
if(dfs(depth + 1, max_depth)) return true;
memcpy(q, w[depth], sizeof q);
}
}
return false;
}
int main()
{
int T;
cin >> T;
while(T --)
{
cin >> n;
for(int i = 0; i < n; i ++ ) cin >> q[i];
int depth = 0;
while(depth < 5 && !dfs(0, depth)) depth ++;
if(depth >= 5) puts("5 or more");
else cout << depth << endl;
}
}
181. 回转游戏 - AcWing题库
/*
0 1
2 3
4 5 6 7 8 9 10
11 12
13 14 15 16 17 18 19
20 21
22 23
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 24;
int q[N];
int op[8][7] = {
{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 center[8] = {6, 7, 8, 11, 12, 15, 16, 17};
int opposite[8] = {5, 4, 7, 6, 1, 0, 3, 2};
int path[100];
int f()
{
static int sum[4];
memset(sum, 0, sizeof sum);
for (int i = 0; i < 8; i ++ ) sum[q[center[i]]] ++ ;
int s = 0;
for (int i = 1; i <= 3; i ++ ) s = max(s, sum[i]);
return 8 - s;
}
void operation(int x)
{
int t = q[op[x][0]];
for (int i = 0; i < 6; i ++ ) q[op[x][i]] = q[op[x][i + 1]];
q[op[x][6]] = t;
}
bool dfs(int depth, int max_depth, int last)
{
int p = f();
if (!p) return true;
if (depth + p > max_depth) return false;
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()
{
while (scanf("%d", &q[0]), q[0])
{
for (int i = 1; i < N; i ++ ) scanf("%d", &q[i]);
int depth = 0;
while (!dfs(0, depth, -1))
{
depth ++ ;
}
if (!depth) printf("No moves needed");
for (int i = 0; i < depth; i ++ ) printf("%c", 'A' + path[i]);
printf("\n%d\n", q[6]);
}
return 0;
}