CodeForces - 518C Anya and Smartphone(链表)

来源:互联网 发布:网络支付方法 编辑:程序博客网 时间:2024/06/11 14:51

题意:

最近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;}
0 0
原创粉丝点击