• Atcoder Grand Contest 037C(贪心,优先队列,思维)


    #define HAVE_STRUCT_TIMESPEC//编译器中time.h和phread.h头文件中timespec结构体重名,故加此行
    #include<bits/stdc++.h>
    using namespace std;
    int a[200007],b[2000007];
    priority_queue<pair<int,int> >q;
    int n;
    int mi(int x){
    return x==1?n:x-1;
    }
    int pl(int x){
    return x==n?1:x+1;
    }
    int main(){
    cin>>n;
    for(int i=1;i<=n;++i)
    cin>>a[i];
    for(int i=1;i<=n;++i){
    cin>>b[i];
    q.push({b[i],i});
    }
    long long ans=0;
    while(!q.empty()){
    int i=q.top().second;
    q.pop();
    if(b[i]==a[i])
    continue;
    if(a[i]>b[i]-b[mi(i)]-b[pl(i)])//如果a[i]>b[i]-b[mi(i)]-b[pl(i)],那么a[i]加上已经等于b[i-1]的a[i-1]和已经等于b[i+1]的a[i+1]就会超过b[i],较小的a[i]会先变成b[i],明显是要小的b[i]先满足题意才能大的b[i]后满足题意,所以如果大的b[i],a[i]+b[i-1]+b[i+1]相加都比b[i]大,那么a[i]就大的无法得到了
    return puts("-1"),0;
    int tmp=b[mi(i)]+b[pl(i)];
    int tot=b[i]-a[i];//tot是还需要加上多少才能让a[i]变成b[i]
    ans+=tot/tmp;//tmp是每次能加上的最大值,这样贪心策略最优
    tot%=tmp;//tot保留余数
    b[i]=a[i]+tot;//b[i]变成一个小的数字,放在优先队列里排序,可以让i-1和i+1在变化的时候用到它,它是a[i]变成原来b[i]的一个中间值
    if(a[i]>b[i])
    return puts("-1"),0;
    if(a[i]!=b[i])
    q.push({b[i],i});//扔进队列等待处理中间值
    }
    cout<<ans;
    return 0;
    }

    保持热爱 不懈努力 不试试看怎么知道会失败呢(划掉) 世上无难事 只要肯放弃(划掉)
  • 相关阅读:
    shell脚本修改Linux系统中所有IP样例
    关闭并卸载数据库脚本
    查询编译不通过的存储过程并重新编译
    SQL函数造数据样例(一)
    类型转换和多态
    Java学习笔记(三)
    Java学习笔记二()
    Java学习笔记(一)
    1.2.零宽断言
    1.3.匹配小括号的字符(可能有小括号在一行的,也有多行的)
  • 原文地址:https://www.cnblogs.com/ldudxy/p/11377538.html
Copyright © 2020-2023  润新知