T1 可以了
做法
考虑先算出总体的平均数记为 $ \Delta $ .
之后我们遍历每一块蛋糕并计算从第一块到当前这一块的蛋糕的平均值 \(x\) 是否 \(\geq \Delta\).
如果满足这个条件,就继续向后拓展,否则就停下.
记得处理边界条件:全都可以的话就直接取第一块,如果第一块就不行的话直接输出 \(-1\).
代码
#include<bits/stdc++.h>
#define ri register int
#define io cin.tie(0),cout.tie(0),ios::sync_with_stdio (false)
#define ll long long
using namespace std;
const ll N = 514514;
ll a[N], n;
long double det_x;
ll ans = -1;
int main()
{
io;
cin >> n;
for ( ri i = 1; i <= n; i++ )
{
cin >> a[i];
det_x += a[i];
}
det_x /= n;
for ( ri i = 1; i <= n; i++ )
{
double tmp = a[i];
ll l = 1;
while ( tmp / l >= det_x )
{
tmp += a[++i];
l++;
if ( i >= n && i - l + 1 <= n )
{
cout << i - l + 1 << "\n";
exit ( 0 );
}
}
}
cout << -1 << "\n";
}
T2 淘汰
做法
一眼顶针为考虑反悔贪心
我们先把那 \(k\) 个可以用加速的先用了,如果这个时候发现已经可以了那直接输出就行,关键在于怎么处理在加速之外的。
之后我们尝试增加一个项目,有两种可能。
1
新加一个 \(a_i\).
2
新加一个 \(b_i\),把之前的 $b_j $ 换成 \(b_j\) 。
所以我们需要维护三个堆:目前不玩项目的 \(a_i\) ,目前不玩的项目的 \(b_i\) ,目前玩的项目里 \(b_i-a_i\)
是换的代价
代码
#include <bits/stdc++.h>
#define ll long long
#define io cin.tie(0), cout.tie(0), ios::sync_with_stdio(false)
#define lb long double
#define ri int
using namespace std;
const int N = 314514;
struct node
{
ll val, id;
bool operator < ( const node&aa ) const
{
return val > aa.val;
}
};
priority_queue<node> q1, q2, q3;
ll ans = 0;
int vis[N];
int a[N], b[N];
int main()
{
io;
int n, k;
cin >> n >> k;
for ( ri i = 1; i <= n; i++ )
{
cin >> a[i] >> b[i];
}
for ( ri i = 1; i <= n; i++ )
{
q1.push ( {a[i], i} );
q2.push ( {b[i], i} );
}
for ( ri i = 1; i <= k; i++ )
{
ll minn = 1e9, op, x, y;
while ( !q1.empty() && vis[q1.top().id] != 0 ) q1.pop();
if ( !q1.empty() && q1.top().val < minn )
{
minn = q1.top().val;
x = q1.top().id;
op = 1;
}
while ( !q2.empty() && vis[q2.top().id] != 1 ) q2.pop();
if ( !q2.empty() && q2.top().val < minn )
{
minn = q2.top().val;
x = q2.top().id;
op = 2;
}
while ( !q3.empty() && vis[q3.top().id] != 1 ) q3.pop();
while ( !q2.empty() && vis[q2.top().id] != 0 ) q2.pop();
if ( !q3.empty() && !q2.empty() && q3.top().val + q2.top().val < minn )
{
minn = q3.top().val + q2.top().val;
x = q3.top().id;
y = q2.top().id;
op = 3;
}
while ( !q2.empty() && vis[q2.top().id] != 0 ) q2.pop();
while ( !q3.empty() && vis[q3.top().id] != 2 ) q3.pop();
if ( !q3.empty() && !q2.empty() && q3.top().val + q2.top().val < minn )
{
minn = q3.top().val + q2.top().val;
x = q3.top().id;
y = q2.top().id;
op = 4;
}
ans += minn;
if ( op == 1 )
{
vis[x] = 1;
q2.push ( {b[x] - a[x], x} );
q3.push ( { -a[x], x} );
}
if ( op == 2 )
{
vis[x] = 2;
q3.push ( { a[x] - b[x], x} );
}
if ( op == 3 )
{
vis[x] = 0;
vis[y] = 2;
q1.push ( { a[x], x} );
q2.push ( { b[x], x} );
q3.push ( { a[y] - b[y], y} );
}
if ( op == 4 )
{
vis[x] = 1;
vis[y] = 2;
q2.push ( { b[x] - a[x], x} );
q3.push ( { -a[x], x} );
q3.push ( { a[y] - b[y], y} );
}
}
cout << ans << endl;
return 0;
}
总结
\(t1\)赛时写了出来,但是数组开小了。
\(t2\) 由于之前看到过很相似的题目所以想到了是反悔贪心,但是具体没想好怎么写,赛时没写出来,一直在调。
\(t3\),\(t4\)看着暴力不好打,直接逃跑。