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的代码大体明白了。