教室里有 nn 排座位。处于疫情防控的目的,希望你空出 mm 排座位, mm 排位置空出后,剩下的座位的相邻两排间隔就会增加,这样就可以减少聚集了。
现在需要你最大化剩余的相邻两个座位间距的最小值,并输出最大化后的结果。
输入格式
第一行两个整数 n,m(1 \leq n \leq 2\times 10 ^5,0 \leq m \leq n)n,m(1≤n≤2×105,0≤m≤n),表示共有 nn 排座位,需要空出 mm 排。
第二行 n - 1n−1整数,第 ii 个整数 d_i(1\leq d_i \leq 10^4)di(1≤di≤104) 表示第 ii 排座位和第 i + 1i+1 排座位间隔距离为 d_idi。
输出格式
一个整数, 表示最大化后的结果。
输入输出样例
输入 #1复制
5 1 2 1 1 2
输出 #1复制
2
输入 #2复制
5 3 1 2 3 4
输出 #2复制
10
答案具有单调性,且最大值最小,优先考虑二分,由于两排间距离不好check,先将其转化为每排的位置坐标,然后通过距离进行check。
r一定要开的够大,比赛时候其实别的都写对了,就是r开小了一直卡在第十个点,补题时候也一直卡在这个点。/(ㄒoㄒ)/~~
#include<bits/stdc++.h>
#define ll long long
using namespace std;
bool ck(ll x);
ll a[222222],s[222222],n,m,l=0,r=0x7fffffff,mid;
int main()
{
cin>>n>>m;
s[1]=0;
memset(a,0,sizeof(a));
memset(s,0,sizeof(s));
for(int i=2;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+a[i];
}
while(l<=r)
{
mid=l+r>>1;
ck(mid)?l=mid+1:r=mid-1;
}
cout<<l-1;
return 0;
}
bool ck(ll x)
{
int p=0,tot=0;
for(int i=2;i<=n;i++)
{
s[i]-s[p]<x?tot++:p=i;
}
return tot<=m;
}
Number Game
题目描述
Alice and Bob are playing a game. They have an array of positive integers aa of size nn .
Before starting the game, Alice chooses an integer k \ge 0k≥0 . The game lasts for kk stages, the stages are numbered from 11 to kk . During the ii -th stage, Alice must remove an element from the array that is less than or equal to k - i + 1k−i+1 . After that, if the array is not empty, Bob must add k - i + 1k−i+1 to an arbitrary element of the array. Note that both Alice's move and Bob's move are two parts of the same stage of the game. If Alice can't delete an element during some stage, she loses. If the kk -th stage ends and Alice hasn't lost yet, she wins.
Your task is to determine the maximum value of kk such that Alice can win if both players play optimally. Bob plays against Alice, so he tries to make her lose the game, if it's possible.
输入格式
The first line contains a single integer tt ( 1 \le t \le 1001≤t≤100 ) — the number of test cases.
The first line of each test case contains a single integer nn ( 1 \le n \le 1001≤n≤100 ) — the size of the array aa .
The second line contains nn integers a_1, a_2, \dots, a_na1,a2,…,an ( 1 \le a_i \le n1≤ai≤n ).
输出格式
For each test case, print one integer — the maximum value of kk such that Alice can win if both players play optimally.
题意翻译
一共有 tt 组数据,每次有一个序列 aa ,两个人对它进行操作,一共进行 kk 个回合。在第 ii 个回合中,第一个人必须在序列 aa 不为空的情况下删除序列 aa 任意一个小于等于 k-i+1k−i+1 的数。接着,第二个人必须在序列 aa 不为空的情况下将 k-i+1k−i+1 加到序列 aa 中任意一个数上。当 kk 个回合结束时,如果第一个人每一回合都操作过了,第一个人就赢了,否则就输了。求保证让第一个人赢的情况下 kk 最大是多少。
输入输出样例
输入 #1复制
4 3 1 1 2 4 4 4 4 4 1 1 5 1 3 2 1 1
输出 #1复制
2 0 1 3
答案是线性的,所以先想到二分,check函数只需模拟二人操作即可,对于二人操作的策略,只需贪心的分别取最大和最小。
#include<bits/stdc++.h>
#define re register
#define ll long long
#define maxn 111
#define INF 0x7fffff
using namespace std;
bool ck(ll x);
ll a[maxn],b[maxn],l,r,mid,t,n;
int main()
{
cin>>t;
while(t--)
{
cin>>n;
l=0;
r=INF;
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
while(l<=r)
{
mid=l+r>>1;
ck(mid)?l=mid+1:r=mid-1;
}
cout<<r<<endl;
}
return 0;
}
bool ck(ll x)
{
for(re int i=1;i<=n;i++)
{
b[i]=a[i];
}
for(re int k=x;k>=1;k--)
{
sort(b+1,b+1+n,greater<int>());
int p=lower_bound(b+1,b+n+1,k,greater<int>())-b;
if(p==n+1)
return 0;
b[p]=INF;
b[n]+=k;
}
return 1;
}