题意:给你一个礼物堆,一个送礼清单,每次从中拿出一个礼物得从最上面开始搬,取出礼物后要将移动过的礼物放回堆中,但顺序可以改变,每一次搬动用时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); } } }