今天上午考试,考到一半左眼开始疼,然后头晕。蓝瘦。。。
T1 优先队列模拟,我想到怎么做了,但是错了两个地方。1,读题不认真题意理解错了。2,正解要优先队列维护一下最值。当时没想到这个数据结构正好暴力模拟。后来证明暴力能那60分。加上优先队列100分。T2暴力模拟30。T3
30分做法暴力跑floyd,当时想起来眼疼的不行再加上不会找子树没尝试,70听学长说是跑n遍O(n)的树的直径,然而也不会做。100好像晚上讲。
总结:认真读题,认真读题,认真读题。遇到问题想想有什么数据结构可以维护。
T1
1.接水
【问题描述】
学校里有一个水房,水房里一共装有 m 个龙头可供同学们打开水,每个龙头每秒钟的供水量
相等,均为 1。
现在有 n 名同学准备接水, 他们的初始接水顺序已经确定。 将这些同学按接水顺序从 1 到 n
编号,i 号同学的接水量为 wi。接水开始时,1 到 m 号同学各占一个水龙头,并同时打开水龙
头接水。 当其中某名同学 j 完成其接水量要求 wj后, 下一名排队等候接水的同学 k 马上接替 j 同
学的位置开始接水。这个换人的过程是瞬间完成的,且没有任何水的浪费。即 j 同学第 x 秒结束
时完成接水,则 k 同学第 x+1 秒立刻开始接水。若当前接水人数 n’不足 m,则只有 n’个龙头
供水,其它 m−n’个龙头关闭。
现在给出 n 名同学的接水量,按照上述接水规则,问所有同学都接完水需要多少秒。
【输入格式】
第 1 行 2 个整数 n 和 m,用一个空格隔开,分别表示接水人数和龙头个数。
第 2 行 n 个整数 w1、w2、……、wn,每两个整数之间用一个空格隔开,wi表示 i 号同学
的接水量。
【输出格式】
输出只有一行,1 个整数,表示接水所需的总时间。
【输入样例】
5 3
4 4 1 2 1
【输出样例】
4
【输入输出样例说明】
第 1 秒,3 人接水。第 1 秒结束时,1、2、3 号同学每人的已接水量为 1,3 号同学接完水,
4 号同学接替 3 号同学开始接水。第 2 秒,3 人接水。第 2 秒结束时,1、2 号同学每人的已接水
量为 2,4 号同学的已接水量为 1。第 3 秒,3 人接水。第 3 秒结束时,1、2 号同学每人的已接水
量为 3,4 号同学的已接水量为 2。4 号同学接完水,5 号同学接替 4 号同学开始接水。第 4 秒,3
人接水。第 4 秒结束时,1、2 号同学每人的已接水量为 4,5 号同学的已接水量为 1。1、2、5 号
同学接完水,即所有人完成接水。
总接水时间为 4 秒。
【数据说明】
对于 30%的数据 1≤n≤100,1≤m≤100
对于 50%的数据 1≤n≤10000,1≤m≤1000
对于 100%的数据 1≤n≤10^6,1≤m≤10000,m≤n,1≤wi≤10000。
//我读成最少要多少时间了,就sort了一下。GG了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
int n,m;
int w[1000000+7];
priority_queue<long long> q;
int main()
{
freopen("water.in","r",stdin);
freopen("water.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
if(m==1)
{
long long ans=0;
for(int i=1;i<=n;i++)
ans+=w[i];
cout<<ans;
}
else
{
for(int i=1;i<=n;i++)
{
if(i<=m)
q.push(-w[i]);
else
{
long long ss=-q.top();
q.pop();
ss+=w[i];
q.push(-ss);
}
}
long long ans;
while (!q.empty())
{
ans=-q.top();
q.pop();
}
cout<<ans;
}
fclose(stdin);
fclose(stdout);
return 0;
}
//得开long long
//2010年普及组t2