题目传送门
sol1:拿到这题的时候刚上完课,讲的是指针。所以一下子就联想到了双向链表。链表可以解决卡片移动的问题,但是无法快速定位要移动的卡片,所以再开一个指针数组,结合数组下标访问的特性快速定位到要移动的卡片。把链表和数组的优势结合起来;
- 双向链表
#include "bits/stdc++.h" using namespace std; const int MAXN = 1e5 + 10; struct Node { Node* pre; int num; Node* nxt; }; Node* a[MAXN]; int main() { int n, m, k; scanf("%d%d", &n, &m); a[0] = new(Node); for (int i = 1; i <= n; i++) { a[i] = new(Node); a[i]->pre = a[i - 1]; a[i - 1]->nxt = a[i]; scanf("%d", &a[i]->num); } a[n + 1] = new(Node); a[n + 1]->pre = a[n]; a[n]->nxt = a[n + 1]; for (int i = 1; i <= m; i++) { scanf("%d", &k); a[k]->nxt->pre = a[k]->pre; a[k]->pre->nxt = a[k]->nxt; a[0]->nxt->pre = a[k]; a[k]->nxt = a[0]->nxt; a[0]->nxt = a[k]; a[k]->pre = a[0]; } for (Node* i = a[0]->nxt; i != a[n + 1]; i = i->nxt) printf("%d ", i->num); return 0; }
sol2:比赛结束后看了别人的题解,发现还可以用栈来实现。越晚操作的牌就在牌堆的越上面。所以只要把牌堆的操作倒着输出就好了,如果这个数已经输出过就不用输了。
- 栈
#include "bits/stdc++.h" using namespace std; const int MAXN = 2e5 + 10; int stk[MAXN]; bool vis[MAXN]; int main() { int n, m; scanf("%d%d", &n, &m); for (int i = n; i >= 1; i--) scanf("%d", &stk[i]); for (int i = n + 1; i <= n + m; i++) scanf("%d", &stk[i]); for (int i = n + m; i >= 1; i--) { if (vis[stk[i]]) continue; printf("%d ", stk[i]); vis[stk[i]] = true; } return 0; }