这个题目还是挺有意思的,回溯,剪枝。
就是枚举所有的移动的情况,然后找出最小的。
代码如下,有助于新人提高;
#include "stdio.h"
#include "string"
#include "stdlib.h"
int min=10000;//初始化min,不停的更新,知道最后dfs的一定是最小值
int dist[11];//位置标记数组
int vis[11];//标记访问数组
void dfs(int cur,int temp)
{
if(temp>min) return;//这个剪枝很重要很重要 否则11!哪有机器承受得了。
if(cur==9) min=temp;//更新 为什么不写if呢 原因是上边<span style="font-family: Arial, Helvetica, sans-serif;">if(temp>min) return; 已经说明了如果大了就直接回溯,如果能到这一步一定是min>temp。</span>
for(int i=1;i<=9;i++)
{
if(!vis[i])//如果没有访问
{
vis[i]=1;//标记访问
for(int k=i+1;k<=10;k++)
if(!vis[k])//接下来这个,因为枚举出来所有的可能性,所以i的下一个i+1不一定在原位置,所以要通过找k来找到需要到哪个位置去。
{
dfs(cur+1,temp+abs(dist[i]-dist[k]));
break;//break很关键,遇到第一个!vis[k]一定就要跳出
}
vis[i]=0;
}
}
return;
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
min=10000;//记得要初始化
memset(vis,0,sizeof(vis));//初始化
for(int i=1;i<=10;i++)
{
int c;scanf("%d",&c);
dist[c]=i;//这样很方便找出位置。
}
dfs(0,0);
printf("%d\n",min);//输出
}
return 0;
}
祝大家acm快乐