题意:
最近Anya买了一个B卓系统的手机,手机上面有n个应用,对应n个图标。
但是屏幕有限,每个屏幕只能容纳k个图标,现在如果你要寻找第k个屏幕上面的应用,
那么你要执行k-1次滑动操作+1次点击操作。当应用启动之后,又重新回到1屏幕。
但是B卓操作系统是个非常屌的操作系统,它能改变图标的顺序,将更频繁地使用图标移动到列表的开始,即除了第一个以外,每打开一个应用就会和前面的应用交换位置。
现在给你n,m,k
接下来n个数字代表起始的图标排列
后面m个数字代表启动应用的顺序
k代表每个屏幕上面有多少个图标
求最少的总操作次数。
解析:
由于数字比较大用n^2的算法肯定超时,所以可以采取构造双向链表的方法。
用一个结构体,里面有3个元素,pre,pos,next。前驱,当前位置,和后继。
查询的时候就输出 (pos-1)/k + 1;注意:这题先把图给画出来比较好下手,不然写链表的时候可能会混乱。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef __int64 ll;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
struct Node {
int pos, pre, next;
}node[N];
int n, m, k;
int main() {
int cur, pre, next;
while(scanf("%d%d%d", &n, &m, &k) != EOF) {
pre = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &cur);
node[pre].next = cur;
node[cur].pos = i;
node[cur].pre = pre;
pre = cur;
}
ll cnt = 0;
while(m--) {
scanf("%d", &cur);
cnt += (node[cur].pos - 1) / k + 1;
if(node[cur].pos == 1) continue;
pre = node[cur].pre;
next = node[cur].next;
int pre_pre = node[pre].pre;
//pre_pre - pre - cur - next
//pre_pre - cur - pre - next
swap(node[cur].pos, node[pre].pos);
node[cur].pre = pre_pre;
node[cur].next = pre;
node[pre].pre = cur;
node[pre].next = next;
node[next].pre = pre;
node[pre_pre].next = cur;
}
printf("%I64d\n", cnt);
}
return 0;
}