备战蓝桥杯---贪心刷题1

话不多说,直接看题:

本质是一个数学题:

我们令xi<0表示反方向传递,易得我们就是求每一个xi的绝对值之和min,我们令平均值为a爸。

易得约束条件:

x1-x2=a1-a,x2-x3=a2-a.....

解得x1=x1-0,x2=x1-((n-1)*a-a2-...an)。。。。

这样就把问题转化成|x1-c1|+|x2-c2|+|...|....

又ci=ci+1+a-ai我们就可以吧c解出来,下面是AC代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
long long n,a[N];
long long sum=0;
long long c[N];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
         scanf("%lld",&a[i]);
         sum+=a[i];
    }
    long long av=sum/n;
    for(int i=n;i>1;i--){
        c[i]=c[i+1]+av-a[i];
    }
    c[1]=0;
    sort(c+1,c+n+1);
    long long res=0;
    for(int i=1;i<=n;i++) res+=abs(c[i]-c[(i+1)/2]);
    cout<<res;
}

接题:

先转换一下,我们从小岛的角度来看,看看每一个小岛可以被覆盖在x轴上对应的范围,这样问题就转换成了给定若干个区间,最少选多少个点可以使得每一个区间至少选了一个点。

如何贪心?我们先按照右端点排序,扫描每一个线段,若上一个右端点不在区间,那么选右端点。

若在则跳过。

如何严格证明?

我们记cnt为算法得到的结果,opt为最优解。

显然选了cnt个,那么就有cnt个互不相交的区间,因此答案一定大于等于cnt+opt是最优解,得证!

下面是AC代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,d;
struct node{
    double l,r;
}seg[N];
bool cmp(node a,node b){
    return a.r<b.r;
}
int main(){
    cin>>n>>d;
    bool ff=0;
    for(int i=0;i<n;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        if(y>d) ff=1;
        else{
            double ck=sqrt(d*d-y*y);
            seg[i].l=x-ck,seg[i].r=x+ck;
        }
    }
    if(ff) cout<<-1<<endl;
    else{
        sort(seg,seg+n,cmp);
        int cnt=0;
        double last=-1000000000;
        for(int i=0;i<n;i++){
            if(last<seg[i].l){
                cnt++;
                last=seg[i].r;
            }
        }
        cout<<cnt;
    }
}

接题:

很容易想到,假如每一个人的钱都比平均大,那么都取平均即可。

假如有一个人少,那么让它填满,剩下的平均分摊给大于平均的。

下面是严格的证明:

我们把方差的每一项看成xi,xi的和为0,由均值不等式知我们要让每一个数尽可能相同,假如有一个小于平均值,假设它不选满,则结果肯定变大。

因此,若a1<平均值,那么我们就取a1,后面的式子满足加起来和为s-a1,因此剩下的加起来就是s-a1-(n-1)/n*s;此时每一个取到(s-a1)/(n-1)是最优的,而若此时大于该值,那么后面的肯定也大(排过序),因此取其即可。

下面是AC代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=500100;
int n,a[N];
int main(){
    long double s;
    scanf("%d%Lf",&n,&s);
    for(int i=0;i<n;i++) scanf("%d",&a[i]);
    sort(a,a+n);
    long double res=0,av=s/n;
    for(int i=0;i<n;i++){
        double cur=s/(n-i);
        if(a[i]<cur) cur=a[i];
        res+=(cur-av)*(cur-av);
        s-=cur;
    }
    printf("%.4Lf\n",sqrt(res/n));
}
相关推荐
IT猿手10 分钟前
基于强化学习的多算子差分进化路径规划算法QSMODE的机器人路径规划问题研究,提供MATLAB代码
算法·matlab·机器人
千逐-沐风10 分钟前
SMU-ACM2026冬训周报3rd
算法
铉铉这波能秀31 分钟前
LeetCode Hot100数据结构背景知识之元组(Tuple)Python2026新版
数据结构·python·算法·leetcode·元组·tuple
晚霞的不甘38 分钟前
Flutter for OpenHarmony 实现计算几何:Graham Scan 凸包算法的可视化演示
人工智能·算法·flutter·架构·开源·音视频
㓗冽1 小时前
60题之内难题分析
开发语言·c++·算法
大江东去浪淘尽千古风流人物1 小时前
【VLN】VLN仿真与训练三要素 Dataset,Simulators,Benchmarks(2)
深度学习·算法·机器人·概率论·slam
铉铉这波能秀1 小时前
LeetCode Hot100数据结构背景知识之字典(Dictionary)Python2026新版
数据结构·python·算法·leetcode·字典·dictionary
蜡笔小马1 小时前
10.Boost.Geometry R-tree 空间索引详解
开发语言·c++·算法·r-tree
唐梓航-求职中2 小时前
编程-技术-算法-leetcode-288. 单词的唯一缩写
算法·leetcode·c#
仟濹2 小时前
【算法打卡day3 | 2026-02-08 周日 | 算法: BFS】3_卡码网99_计数孤岛_BFS | 4_卡码网100_最大岛屿的面积DFS
算法·深度优先·宽度优先