C题:用桶处理字符串重排
小红拿到了一个字符串,其中一定包含连续子串"xiao",和连续子串"hong"。
请你将字符串重排,使得该字符串包含"xiaohong"的连续子串。
- 较简单的做法:遍历字符串,给每个字符放到相应的桶中,然后先先输出目标字符串xiaohong,同时对桶进行相对应的调整。最后再按任意顺序输出桶中字符。
- 赛时我的复杂做法:先找到xiaohong的每个字符在给出字符串的位置,由于重复也需要桶,对于位置标记,最后输出时跳过这些位置。
D题:中位数理解加深,可删除对顶堆杀鸡用牛刀
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| double ans[N]; int a[N];
class MedianFinder { priority_queue<int, vector<int>, greater<int>> minheap; priority_queue<int> maxheap; unordered_map<int, int> delayed; int minSize, maxSize; //decrease delayed
template <typename T> void prune(T &heap) { while (!heap.empty()) { int num = heap.top(); if (delayed.count(num)) { delayed[num]--; if (delayed[num] == 0) delayed.erase(num); heap.pop(); } else break; } }
void makebalance() { if (maxSize > minSize + 1) { minheap.push(maxheap.top()); maxheap.pop(); minSize++; maxSize--; prune(maxheap); } else if (maxSize < minSize) { maxheap.push(minheap.top()); minheap.pop(); maxSize++; minSize--; prune(minheap); } }
public: MedianFinder() : minSize(0), maxSize(0) {}
void insert(int num) { if (minheap.empty() && maxheap.empty()) { maxheap.push(num); maxSize++; } else { int topnum = maxheap.top(); if (topnum < num) { minheap.push(num); minSize++; } else { maxheap.push(num); maxSize++; } } makebalance(); }
void erase(int num) { delayed[num]++; if (num <= maxheap.top()) { maxSize--; if (num == maxheap.top()) prune(maxheap); } else { minSize--; if (num == minheap.top()) prune(minheap); } makebalance(); }
double getMedian() { if (minSize == maxSize) return ((double)minheap.top() + maxheap.top()) / 2; //防范int溢出 else return (double)maxheap.top(); } };
int main() { MedianFinder mf;
// 插入一些数据 cin>>n; for(int i=1;i<=n;i++){cin>>a[i];mf.insert(a[i]);} // mf.insert(3); // mf.insert(1); // mf.insert(5); // mf.insert(8); // mf.insert(2); for(int i=1;i<=n;i++){ mf.erase(a[i]); //cout<<mf.getMedian() << endl; baoliu(mf.getMedian(),1);cout<<endl; mf.insert(a[i]); } // // 输出当前中位数 // cout << "Current median: " << mf.getMedian() << endl; // // // 删除一个元素 // mf.erase(1); // // // 再次输出中位数 // cout << "Updated median: " << mf.getMedian() << endl;
return 0; }
|
正解:对长度为奇数和偶数分别处理,核心思想,
当处理左边的数的时候,中位数是固定的。
当处理右边的数的时候,中位数是固定的。
中间只有一个数特别处理一次就够
需要注意细节
E题:给定一组数,要求重排以后相邻元素不相同。如果可行需要给出方案
(不过就是套了一个质因数分解的皮)
做法:如果就题论题的数,我们应该考虑直接暴力,赛时就应该以通过为第一优先级,看了hls的代码大体明白了。