• CCPC 2019 网络赛 1006 Shuffle Card


    // 签到题,比赛时候写双向链表debug了半天,发现有更好方法,记录一下。
     

    Shuffle Card HDU 6707

    题意:

      有一 (n) 张卡片,编号 (1~n) ,给定初始编号排列和 (m) 次操作,每次操作将编号为 (s_i) 的卡片放到第一张上面。求最后卡片的编号序列。
     

    思路:

      直接想法就是模拟,复杂度 (O(nm)) ,会T掉。如果采用双向链表储存编号,每次洗牌操作复杂度都是 (O(1)) ,总复杂度(O(m)),可行。比赛时候写链表少连了一条边调了半天
      双向链表交换两个节点太麻烦了,今天发现可以直接用,输出序列标出上面已拿出的卡片编号即可,复杂度 (O(n+m))
     

    AC代码1:

     // 栈实现
    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    const int maxn = 100010;
    
    bool vis[maxn];
    int arr[maxn];
    vector<int> S;
    
    int main() {
    	int n, m;
    	cin>>n>>m;
    	for(int i=0;i<n;i++) {
    		scanf("%d", &arr[i]);
    	}
    	for(int i=n-1;i>=0;i--) {
    		S.push_back(arr[i]);
    	}	
    	while(m--) {
    		int card; scanf("%d", &card);
    		S.push_back(card);
    	}
    	int left = n;
    	while(!S.empty() && left) {
    		int now = *--S.end();
    		if(!vis[now]) {
    			printf("%d ", now);
    			vis[now] = 1;
    			--left;
    		}
    		S.pop_back();
    	}
    	return 0;
    }
    

    AC代码1:

     // 双向链表实现
    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    const int maxn = 100010;
    
    struct node {
    	int pre, next;
    }cards[maxn];
    int head;
    
    int arr[maxn];
    
    int main() {
    	int n, m;
    	cin>>n>>m;
    	for(int i=1;i<=n;i++) {
    		scanf("%d", &arr[i]);
    	}
    
    	head = arr[1];
    	cards[arr[1]].pre = -1;
    	cards[arr[n]].next = -1;
    	for(int i=1;i<n;i++) {
    		cards[arr[i]].next = arr[i+1];
    		cards[arr[i+1]].pre = arr[i];
    	}
    	
    
    	while(m--) {
    		int c; scanf("%d", &c);
    		if(c==head) continue;
    
    		int h = c;	// 新的头结点
    		int pre = cards[c].pre;
    		int next = cards[c].next;
    
    		if(pre!=-1)
    			cards[pre].next = next;
    		if(next!=-1)
    			cards[next].pre = pre;
    
    		cards[c].next = head;
    		cards[head].pre = c;   // 别忘了这一行!!!
    		cards[c].pre = -1; 
    		head = c;
    
    	}
    
    	int p = head;
    	while(p!=-1) {
    		printf("%d ", p);
    		p = cards[p].next;
    	}
    	return 0;
    }
    
  • 相关阅读:
    ios 手势加变形
    ios 懒加载
    [leetCode]1111. 有效括号的嵌套深度
    [leetCode]面试题 08.07. 无重复字符串的排列组合
    [leetCode]46. 全排列
    [leetCode]37. 解数独
    [leetCode]面试题 08.09. 括号
    torch.Tensor 与 numpy.ndarray的相互转化
    [leetCode]93. 复原IP地址
    [leetCode]15. 三数之和
  • 原文地址:https://www.cnblogs.com/izcat/p/11424120.html
Copyright © 2020-2023  润新知