摆书 book

题目描述:

  dxy家收藏了一套书,这套书叫《SDOI故事集》,《SDOI故事集》有n(n≤19)本,每本书有一个编号,从1号到n号。

  dxy把这些书按编号从小到大,从上往下摞成一摞。dxy对这套书极其重视,不允许任何人动这套书。

  有一天Evensgn到dxy家玩,dxy因为和妹子有约会,就让Evensgn自己待在他家。Evensgn对这套书非常好奇,偷偷的看了一下,结果发现这里面竟然有当年小E和小Q的故事。Evensgn看得出神,结果把一摞书的顺序打乱了。

  眼看着dxy就要回来了,Evensgn需要尽快把这摞书恢复到原先排好序的状态。由于每本书都非常重,所以Evensgn能做的操作只有把一本书从书堆中抽出来,然后把这本书放到书堆的顶部。

  给你打乱的书的顺序,你能帮Evensgn算算最少需要几次上述的操作,他才能把这套书恢复顺序?假如你能算出来的话,Evensgn答应送给你一本他签名的书《SDOI故事集9:小E的故事》

 

输入格式:

  输入包含多组数据。

  第一行包含一个正整数T(T≤30)表示数据组数。

  对于每组数据,第一行为一个正整数n表示这套《SDOI故事集》中有多少本书。

  接下来一行n个用空格分开的正整数,表示Evensgn打乱后的这摞书的书号顺序(从上往下)。

输出格式:

  对于每组数据,输出一行一个整数,表示Evensgn最少需要几次操作才能讲书恢复顺序。

数据范围:

  存在 50% 的数据,n<=10

  另外存在 30% 的数据,n<=1000

  对于 100% 的数据,n<=100000

Solution:

  从题目描述中可以得出,我们就是将一列无序的序列进行排序,排序的方法是从序列中间随机取数放到序列的最前端,求最小的移动次数,使得序列递增。

  那我们就可以发现,我们必须将逆序的数对 a-1, , , …, , ,a 中的a提到最前面,然后比他小的都需要一次提前。所以,我们找到需要提前的数中最大的那个即可求出最终的答案。

 1 #include<cstdio>
 2 using namespace std;
 3 const int maxn=1e5+5;
 4 int ord[maxn],a[maxn];
 5 inline int max(int a,int b){return a>b?a:b;}
 6 inline int read(){
 7     char ch=getchar();
 8     int x=0,f=1;
 9     while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
10     while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
11     return x*f;
12 }
13 int main(){
14     freopen("book.in","r",stdin);
15     freopen("book.out","w",stdout);
16     int t=read(),n,ans=0;
17     while(t--){
18         n=read(),ans=0;
19         for(int i=1;i<=n;i++) a[i]=read(),ord[a[i]]=i;
20         for(int i=1;i<=n;i++)
21             if(ord[a[i]+1]<ord[a[i]]&&a[i]+1<=n) ans=max(ans,a[i]);
22         printf("%d\n",ans);
23     }
24     return 0;
25 }
26 /*
27 100
28 5
29 4 3 5 1 2
30 4
31 4 1 2 3
32 5
33 1 2 3 4 5
34 5
35 3 2 1 5 4
36 6
37 6 5 4 3 2 1
38 7
39 1 2 3 5 4 6 7
40 
41 Ans:
42 3
43 3
44 0
45 4
46 5
47 4
48 */
View Code

 

posted @ 2018-07-12 14:55  Rising_Date  阅读(275)  评论(0编辑  收藏  举报