翻煎饼
正解部分
这里有道类似的 题目
使用 迭代搜索, 最多只能跑过 n=7 的数据, 需要剪枝,
每次旋转相邻数字之间的差值变化最微小, 翻转一次仅有一对数字间的差的绝对值会发生改变, 于是统计有 cnt数字间绝对值不为 1, 则至少需要 cnt 次操作到终态, 依此进行剪枝 .
实现部分
没什么好说的 …
#include<bits/stdc++.h>
#define reg register
const int maxn = 25;
int N;
int A[maxn];
int tmp[maxn];
bool flag;
bool chk(){
for(reg int i = 1; i <= N; i ++)
if(tmp[i] != i) return 0;
return 1;
}
int chk_2(){
int s = 0;
for(reg int i = 1; i < N; i ++)
if(abs(tmp[i]-tmp[i+1]) != 1) s ++;
return s;
}
void DFS(int k, int lim){
if(chk()){ flag = 1; return ; }
if(k == lim+1) return ;
if(k-1+chk_2() > lim) return ;
for(reg int i = 1; i <= N; i ++){
int mid = 1+i >> 1;
std::reverse(tmp+1, tmp+i+1);
// for(reg int j = 1; j <= mid; j ++) std::swap(tmp[j], tmp[i-j+1]);
DFS(k+1, lim);
std::reverse(tmp+1, tmp+i+1);
// for(reg int j = 1; j <= mid; j ++) std::swap(tmp[j], tmp[i-j+1]);
}
}
int main(){
scanf("%d", &N);
for(reg int i = 1; i <= N; i ++) scanf("%d", &A[i]);
for(reg int k = 1; ; k ++){
flag = 0;
for(reg int i = 1; i <= N; i ++) tmp[i] = A[i];
DFS(1, k);
if(flag){
printf("%d\n", k);
return 0;
}
}
return 0;
}