页
Description
战神阿瑞斯听说2008年在中华大地上,将举行一届规模盛大的奥林匹克运动会,心中顿觉异常兴奋,他想让天马在广阔的天空上,举行一场精彩的天马队列变换表演。首先,战神安排n头高度不同的天马,排成一列。然后重复下面的变换:让中间的天马出列,然后该匹天马可以排在对首,也可以排在队尾,这样称为一次变换,直到出现这一列天马按从低到高的顺序排列为止。那么从初始状态到目标状态最少需要多少次变换呢?你能给战神阿瑞斯参谋参谋吗?
Input
输入文件horse.in中有两行,第一行只有一个整数n,表示天马数。
第二行有n个正整数,分别表示n匹天马的高度,每两个数字中间用一个空格分隔。
Output
输出文件horse.out只有一行,该行只有一个正整数,表示从初始状态到目标状态最少需要的变换次数。如果无论如何变换都不能得到从低到高的排列,则输出已行“No Answer”(不包括引号)。
Sample Input
3
179 173 175
Sample Output
2
Hint
【数据限制】
100%的数据:n只取3、5、7、9四个数字中的一个,且天马的高度为160-190之间的整数。
反思&题解
比赛思路: 暴力,多于100退出(其实可以很多分的,但是我取序列中间时忘记+1了,结果炸了)
正解思路: 听PZR巨佬说多于20就可以退出来,因为最大一个点答案只有20 (真是个很好用的奇技淫巧) ,正解是BFS+Hash,不过CZJ巨佬用trie代替Hash也可以过
反思: 还是细节问题
CODE
#include<bits/stdc++.h>
using namespace std;
int n,a[10],ans;
bool pd()
{
int i;
for (i=1;i<n;i++)
if (a[i]>a[i+1]) return false;
return true;
}
void dfs(int tot)
{
if (tot>100) return;
if (tot>=ans) return;
if (pd()) ans=tot;
else
{
int i,x=a[n/2+1];
for (i=n/2+1;i>=2;i--)
a[i]=a[i-1];
a[1]=x;
dfs(tot+1);
x=a[1];
for (i=1;i<=n/2;i++)
a[i]=a[i+1];
a[n/2+1]=x;
x=a[n/2+1];
for (i=n/2+1;i<=n-1;i++)
a[i]=a[i+1];
a[n]=x;
dfs(tot+1);
x=a[n];
for (i=n;i>=n/2+2;i--)
a[i]=a[i-1];
a[n/2+1]=x;
}
}
int main()
{
scanf("%d",&n);
int i;
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
ans=123456;
dfs(0);
if (ans!=123456) printf("%d\n",ans);
else printf("No Answer");
return 0;
}