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