怪异的洗牌

怪异的洗牌

http://www.nowcoder.com/questionTerminal/1801ea11cc9d4732a7f0cb2b0b75c8cf

思路

模拟整个过程就好了,数组循环移位+数组逆序

#include<iostream>
#include<vector>
#include<numeric>

using namespace std;

void shift_flip(vector<int>& cards, int n, int k){
    vector<int> nums = cards;
    // shift
    for(int i = 0; i < n; i ++)
        cards[i] = nums[(i + k) % n];
    // flip
    for(int i = 0; i < n/4; i ++)
        swap(cards[i], cards[n/2 - i - 1]);
}

int main(){
    int n, k;
    while(cin >> n >> k){
        vector<int> cards(n);
        iota(cards.begin(), cards.end(), 1);
        int x;
        for(int i = 0; i < k; i ++){
            cin >> x;
            shift_flip(cards, n, x);
        }
        for(int card : cards)
            cout << card << " ";
        cout << endl;
    }
    return 0;
}

我们来看下另外一种方法 - 经典的三次翻转法,我们可以这么做:

  • 先把[0, x - 1]翻转
  • 然后把[x, n - 1]翻转
  • 最后把[0, n - 1]翻转

img

#include<iostream>
#include<vector>
#include<numeric>
#include<algorithm>

using namespace std;

void shift_flip(vector<int>& cards, int n, int k){
    // shift
    reverse(cards.begin(), cards.begin() + k);
    reverse(cards.begin() + k, cards.end());
    reverse(cards.begin(), cards.end());
    // flip
    for(int i = 0; i < n/4; i ++)
        swap(cards[i], cards[n/2 - i - 1]);
}

int main(){
    int n, k;
    while(cin >> n >> k){
        vector<int> cards(n);
        iota(cards.begin(), cards.end(), 1);
        int x;
        for(int i = 0; i < k; i ++){
            cin >> x;
            shift_flip(cards, n, x);
        }
        for(int card : cards)
            cout << card << " ";
        cout << endl;
    }
    return 0;
}
算法题解 文章被收录于专栏

不定期更新一些算法题解,有什么问题可以随时留言~

全部评论

相关推荐

程序员花海_:实习和校招简历正确格式应该是教育背景+实习+项目经历+个人评价 其中项目经历注意要体现业务 实习经历里面的业务更是要自圆其说 简历模板尽可能保持干净整洁 不要太花哨的
点赞 评论 收藏
分享
面了100年面试不知...:被割穿了才想起来捞人了
投递哔哩哔哩等公司6个岗位
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务