纪中暑假集训 2020.08.11【NOIP提高组】模拟 T3:页

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;	
} 

猜你喜欢

转载自blog.csdn.net/CMC_YXY/article/details/107943040