102. 最佳牛围栏
是一个二分的题目,但是check函数很难想。
因为是浮点型,所以二分格式中就不需要-1了。
题目要求的是最大的平均值。那么我们就二分来求平均值。
传进去的参数mid 是我们假定的平均值。
然后计算每个数对这个平均值的影响。
然后通过前缀和,快速得到某一段区间对这个平均值的收益。
如果这个区间大于等于m并且收益大于0。就说明这个不是最大的平均值。
现在的问题是怎么确定这个区间。
我们用一个数,来存前面的k个数对平均值收益最小的值。
因为如果这个区间加上后面的那个数之后,如果后面那个数比平均值小,那么肯定前k+1个数的收益现在是最小的了,那么肯定不会选这个第k+1个数。而是从k+2开始往后面选大于等于m个数。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int inf=0x3f3f3f3f;
const int MAXN=1e5+10;
int n,m,T;
int flag;
double a[MAXN];
double pre[MAXN];
bool check(double mid){
for(int i=1;i<=n;i++){
pre[i]=pre[i-1]+a[i]-mid;//计算与mid的差距
}
double minn=0;
for(int i=0,j=m;j<=n;i++,j++){//j=m开始时因为 题目给出了条件,要求的至少长度
minn=min(minn,pre[i]);
if(pre[j]-minn>=0){
return true;
}
}
return false;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
double r=0,l=0;
for(int i=1;i<=n;i++){
cin>>a[i];
r=max(r,a[i]);
}
while(r-l>1e-5){
double mid=(r+l)/2;
if(check(mid)){
l=mid;
}else{
r=mid;
}
}
cout<<(int)(r*1000)<<endl;
return 0;
}
103. 电影
就是一个简单的排序。运用map都不需要离散化了。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int inf=0x3f3f3f3f;
const int MAXN=2e5+10;
int n,m,T;
int flag;
struct node{
int a,b;
int set;
};
node v[MAXN];
bool cmp(node x,node y){
if(x.a==y.a){
return x.b>y.b;
}
return x.a>y.a;
}
int a[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
map<int,int>mp;//放会这种语言的人数
for(int i=1;i<=n;i++){
cin>>a[i];
mp[a[i]]++;
}
cin>>m;
for(int i=1;i<=m;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
int b;
cin>>b;
v[i].a=mp[a[i]],v[i].b=mp[b];
v[i].set=i;
}
sort(v+1,v+1+m,cmp);
cout<<v[1].set<<endl;
return 0;
}
104. 货仓选址
一点贪心,很容易看出。取中位数距离是最短的。
如果是奇数就是正中间那个数,如果是偶数,则在中间两个数之间就行。包括这两个数。
排完序,确定位置。然后将数组遍历一遍即可。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int inf=0x3f3f3f3f;
const int MAXN=1e5+10;
int n,m,T;
int flag;
int a[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
int sum=0;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
int mid=(n+1)/2;
for(int i=1;i<=n;i++){
sum+=abs(a[mid]-a[i]);
}
cout<<sum<<endl;
return 0;
}