C

题意:给你一个礼物堆,一个送礼清单,每次从中拿出一个礼物得从最上面开始搬,取出礼物后要将移动过的礼物放回堆中,但顺序可以改变,每一次搬动用时1s,

   要求搬动次数/时间最少。

思路:取出一个礼物后,搬回的时候将下一个放最上面。用一个mx记录搬动的最大深度,之前可以到大的最深位置大于现在该礼物的位置,说明之前的礼物可以排序。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int c[N];
int main(){
        int t,m,n,a[N],b[N],i,j,mx;
        long long int sum;
        while(~scanf("%d",&t)){
                while(t--){
                        memset(a,0,sizeof(a));
                        memset(b,0,sizeof(b));
                        memset(c,0,sizeof(c));
                        scanf("%d %d",&n,&m);
                        for(i=1;i<=n;i++){
                                scanf("%d",&a[i]);
                                c[a[i]]=i;
                        }
                        for(i=1;i<=m;i++){
                                scanf("%d",&b[i]);
                        }
                        mx=-1;//记录可以拿到的最大位置
                        for(i=1,sum=0;i<=m;i++){
                                //之前可以到大的最深位置大于现在该礼物的位置,说明之前的礼物可以排序
                                //排序后的下一个礼物可以放置在最顶端
                                if(c[b[i]]<mx){
                                        sum++;
                                }else{
                                        sum+=((c[b[i]]-i)*2);//现在的位置减去拿走礼物的数量
                                        sum++;
                                        mx=c[b[i]];//可以更新最大位置
                                }
                        }
                        printf("%lld
",sum);
                }
        }
}
View Code
原文地址:https://www.cnblogs.com/DreamingBetter/p/12206414.html