版权声明:本文为DyingShu原创文章,转载请注明出处哦。 https://blog.csdn.net/DyingShu/article/details/82250985
努力刷完NOIP提高组题目ing…
50~60分算法:直接用堆/优先队列模拟
100分算法:观察题目,发现其中隐含的单调性。
设两条蚯蚓长度为
,其中
。
则
被切掉时长度分别为
,过t秒之后长度为
此时
被取出,长度
,被切之后长度分别为
显然a的两段长度还是大于b的两段。
由此,我们可以建立3个队列,分别是没切过的蚯蚓,切过之后较长的一段蚯蚓,切过之后较短的一段蚯蚓。
- 每次比较三个队列的队头(因为满足单调性),取出最长的一段切掉,把长的一段和短的一段分别加到两个队列中。
注意细节。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int q[3][20000001], l[3], r[3];
inline int read(){
int k = 0; char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9') k = (k<<3) + (k<<1) + ch - 48, ch = getchar();
return k;
}
inline bool cmp(int a, int b){
return a > b;
}
inline int Find_Max(){
int Max = -0x7fffffff, opt = 0;
for(int i = 0; i < 3; i++)
if(l[i] <= r[i] && q[i][l[i]] > Max)
Max = q[i][l[i]], opt = i;
return opt;
}
int main(){
int n = read(), m = read(), R = read();
int U = read(), V = read(), t = read();
for(int i = 1; i <= n; i++){
q[0][i] = read();
}
sort(q[0] + 1, q[0] + n + 1, cmp); l[0] = 1, r[0] = n;
l[1] = l[2] = 1, r[1] = r[2] = 0;
int tag = 0;
for(int i = 1; i <= m; i++){
int opt = Find_Max();
int u = q[opt][l[opt]++] + tag; tag += R;
int Worm1 = (int)((long long)u * U / V), Worm2 = u - Worm1;
if(Worm2 > Worm1) swap(Worm2, Worm1);
q[1][++r[1]] = Worm1 - tag, q[2][++r[2]] = Worm2 - tag;
if(i % t == 0) printf("%d ", u);
}
printf("\n");
for(int i = 1; i <= n + m; i++){
int opt = Find_Max();
if(i % t == 0) printf("%d ", q[opt][l[opt]] + tag);
l[opt]++;
}
return 0;
}