题意:对于一段数字,每次可以剪切一段连续的自然数,粘贴到任意部分,使其变成升序
思路:
考虑的是进行搜索,深搜并不能保证是最短,广搜感觉每层的情况太多。
迭代加深:枚举搜索深度,然后进行深搜。
这种方法比较适用于不知道明显深度的,以及每层展开情况过多而导致bfs不行的。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <algorithm>
typedef long long ll;
using namespace std;
int maxd;
int n;
struct node
{
int matrix[12];
};
int get_h(node t) //可能进行的最大深度
{
int num = 0,i;
for(i = 1; i < n; i++)
if(t.matrix[i] + 1 != t.matrix[i+1])
num ++;
if(t.matrix[i] != n)
num++;
return num;
}
node change(int from,int to,int x,node t) //利用数组替代指针
{
int tot;
int next[20],tmp[20];
for(int i=0; i <= n; i++)
tmp[i]=t.matrix[i],next[i]=i+1;
next[from-1]=to+1;
next[x]=from;
next[to]=x+1;
for(int i=next[0],tot=1; tot<=n; i=next[i],tot++)
{
t.matrix[tot]=tmp[i];
}
return t;
}
bool dfs(node cur,int tt)
{
int h = get_h(cur);
int flag = 1;
for(int i = 1; i <= n; i++)
{
if(cur.matrix[i] != i);
{
flag = 0;
break;
}
}
if(flag )
return true;
if(tt == maxd)
return h == 0;
if(tt*3+h > maxd*3)
return false;
for(int from = 1; from <= n; from++)
for(int to = from; to <= n; to++)
for(int i = 0; i <= n; i++)
{
node tp;
memcpy(tp.matrix,cur.matrix,sizeof(int)*(n+1));
if(i >= from-1 && i <= to)
continue;
tp = change(from,to,i,tp);
if(dfs(tp,tt+1))
return true;
}
return false;
}
char ch;
int main()
{
int cas = 1;
while(scanf("%d",&n) && n)
{
node from;
for(int i = 1; i <= n; i++)
scanf("%d",&from.matrix[i]);
for(maxd = 0;; maxd++) //搜索深度
{
if(dfs(from,0))
break;
}
printf("Case %d: %d\n",cas++,maxd);
}
return 0;
}