C题:用桶处理字符串重排
小红拿到了一个字符串,其中一定包含连续子串"xiao",和连续子串"hong"。
请你将字符串重排,使得该字符串包含"xiaohong"的连续子串。
- 较简单的做法:遍历字符串,给每个字符放到相应的桶中,然后先先输出目标字符串xiaohong,同时对桶进行相对应的调整。最后再按任意顺序输出桶中字符。
- 赛时我的复杂做法:先找到xiaohong的每个字符在给出字符串的位置,由于重复也需要桶,对于位置标记,最后输出时跳过这些位置。
D题:中位数理解加深,可删除对顶堆杀鸡用牛刀
- 不动脑子:直接使用可删除对顶堆:
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的代码大体明白了。