大部分是从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;
}
}