Loading

JZOJ2020年8月11日提高组T3 页

JZOJ2020年8月11日提高组T3 页

题目

Description

战神阿瑞斯听说2008年在中华大地上,将举行一届规模盛大的奥林匹克运动会,心中顿觉异常兴奋,他想让天马在广阔的天空上,举行一场精彩的天马队列变换表演。首先,战神安排n头高度不同的天马,排成一列。然后重复下面的变换:让中间的天马出列,然后该匹天马可以排在对首,也可以排在队尾,这样称为一次变换,直到出现这一列天马按从低到高的顺序排列为止。那么从初始状态到目标状态最少需要多少次变换呢?你能给战神阿瑞斯参谋参谋吗?

Input

输入文件horse.in中有两行,第一行只有一个整数n,表示天马数。
第二行有n个正整数,分别表示n匹天马的高度,每两个数字中间用一个空格分隔。

Output

输出文件horse.out只有一行,该行只有一个正整数,表示从初始状态到目标状态最少需要的变换次数。如果无论如何变换都不能得到从低到高的排列,则输出已行“No Answer”(不包括引号)。

Sample Input

3
179 173 175

Sample Output

2

Data Constraint

100%的数据:n只取3、5、7、9四个数字中的一个,且天马的高度为160-190之间的整数。

题解

题意

\(n\)个160~190的整数,每次操作将会让最中间的数移植最左或最有
问要多少次操作使得序列单调递增

分析

\(n\)那么小
不暴力对的起这道题吗
上界的话,根据某某某定理(一下省略1000字)[大意就是:出题人用脚出数据的定理]
开20就可以了

Code

#include<cstdio>
#include<algorithm>
#define inf 2147483647
using namespace std;
int n,i,ans,a[10],Sort[10],id[10];
bool b[10];
bool judge()
{
    int i;
    for (i=1;i<=n;i++)
        if (a[i]!=Sort[i]) return false;
    return true;
}
void change1(int l,int r)
{
    int i,t,tid;
    t=a[r];
    tid=id[r];
    for (i=r;i>l;i--)
        a[i]=a[i-1],id[i]=id[i-1];
    a[l]=t;   
    id[l]=tid;
}
void change2(int l,int r)
{
    int i,t,tid;    
    t=a[l];
    tid=id[l];
    for (i=l;i<r;i++)
        a[i]=a[i+1],id[i]=id[i+1];
    a[r]=t; 
    id[r]=tid;
}
bool all()
{
    int i;
    for (i=1;i<=n;i++)
        if (b[i]==false) return false;
    return true;
}
void dg(int s)
{
    if (s>=ans) return;
    if (s>20) return;
    if (judge()==true) ans=min(ans,s);
    int mid=(1+n)>>1;
    change1(1,mid);
    dg(s+1);
    change2(1,mid);
    change2(mid,n);
    dg(s+1);
    change1(mid,n);
}
int main()
{
    scanf("%d",&n);
    for (i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        Sort[i]=a[i];
        id[i]=i;
    }
    sort(Sort+1,Sort+n+1);
    ans=inf;
    dg(0);
    if (ans==inf) printf("No Answer\n");
    else printf("%d\n",ans);
    return 0;
}

posted @ 2020-08-11 20:10  Thunder_S  阅读(121)  评论(0编辑  收藏  举报