CodeTop原创题题解(部分)

大部分是从CodeTop上看到的,少数来自牛客
部分题解,不保证正确性,仅记录自己的思考当作笔记

第一题

题目:\(n\)张牌 牌号\(1\)\(n\),乱序,每次从中抽一张放到牌顶,最终从上到下递增,问最小执行多少次?
来自 https://codetop.cc/discuss/68
方法:
上限是N次,因为我们可以每次将最大的放到牌顶;
所以我们只需要考虑有多少张牌不需要被抽,没被抽\(k\)张牌,必然按原顺序沉到最底下
我们可以找从后往前找\(n, n-1, n-2, ...\),可以不连续
例如,\(1 3 2 4 5\), \(3 4 5\)可以不动,抽\(1\)\(2\)

点击查看代码
// 最少抽牌次数
int shuffle_cards(vector<int>& cards) {
    int n = cards.size(), pre = n, cnt = 0;
    for(int i = n-1;i >= 0;i--) {
        if(cards[i] == pre) {
            pre--;
            cnt++;
        }
    }
    return n-cnt;
}

第二题

题目:给你一堆螺丝和一堆螺母,螺丝之间无法比较大小,螺母之间无法比较大小,但是螺丝和螺母是能比较的,能知道是螺丝大了还是螺母大了, 还是刚好匹配。现在设计一种算法,示例也由自己设计,实现一下如何在最快的时间内对这堆螺丝螺母进行匹配。可以假设这两堆螺丝和螺母肯定是能一一匹配的。
来自:https://codetop.cc/discuss/87
方法:
快速排序变形
先指定一个螺丝,能将螺母划分好,并且能得到这个螺丝对应的螺母;再用这个螺母将螺丝划分好。对划分好的区间递归。

代码实现参考 https://www.jiuzhang.com/solution/nuts-bolts-problem/

点击查看代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<random>
#include<time.h>
using namespace std;

struct Comparator {
    int operator()(const string& s1_, const string& s2_) const{
        string s1 = s1_, s2 = s2_;    // copy, because operator() is const
        transform(s1.begin(), s1.end(), s1.begin(),[](char c){ return toupper(c); });
        transform(s2.begin(), s2.end(), s2.begin(),[](char c){ return toupper(c); });
        if(s1 == s2)  return 0;
        return s1 < s2 ? -1 : 1;
        // return s1 < s2;
    }
};

int split(vector<string>& NorB, string pivot, Comparator compare, int start, int end){
    int i = start;
    string temp = NorB[start];
    for(int j = i+1; j <= end; j++) {
        if(compare(NorB[j], pivot) == -1) {  // 小于
            i++;
            swap(NorB[i], NorB[j]);
        }
        if(compare(NorB[j], pivot) == 0) {  // 相等
            swap(NorB[j], NorB[start]);
            j--;
        }
    }
    swap(NorB[start], NorB[i]);
    return i;
}

void quicksort(vector<string>& nuts, vector<string>& bolts, Comparator compare, int start, int end){
    if(start >= end) return;
    int index = split(nuts, bolts[start], compare, start, end);
    split(bolts, nuts[index], compare, start, end);
    quicksort(nuts, bolts, compare, start, index-1);
    quicksort(nuts, bolts, compare, index+1, end);
}

void sortNutsAndBolts(vector<string> &nuts, vector<string> &bolts, Comparator compare) {
    int n = nuts.size();
    quicksort(nuts, bolts, compare, 0, n-1);
}

int main() {
    Comparator compare;
    // cout << compare("ab", "AB") << endl;
    // cout << compare("ab", "CD") << endl;
    // cout << compare("ef", "CD") << endl;
    vector<string> nuts = {"ab", "cd", "ef", "gh", "ij", "kl", "mn", "op", "qr", "st", "uv", "wx", "yz"};
    vector<string> bolts = {"AB", "CD", "EF", "GH", "IJ", "KL", "MN", "OP", "QR", "ST", "UV", "WX", "YZ"};
    shuffle(bolts.begin(), bolts.end(), default_random_engine(time(0)));  // 打乱一个就可以了
    // shuffle(nuts.begin(), nuts.end(), default_random_engine(time(0)));  // 由于随机种子相同,打乱两个会一模一样
    for(int i = 0; i < nuts.size(); i++) {
        cout << nuts[i] << " " << bolts[i] << endl;
    }
    cout << "************" << endl;
    sortNutsAndBolts(nuts, bolts, compare);
    for(int i = 0; i < nuts.size(); i++) {
        cout << nuts[i] << " " << bolts[i] << endl;
    }
}
posted @ 2021-12-28 15:39  Rogn  阅读(293)  评论(0编辑  收藏  举报