2021牛客寒假算法基础集训营3 B内卷(优先队列+尺取法)。经典@@!

题目:https://ac.nowcoder.com/acm/contest/9983/B

题解:枚举法--枚举最小值,然后其他每组选择与其差值最小的数即可。

具体见兰子哥哥

翻译:最开始,魅族都选最小的只,就相当于以最小的数作为最小的数的最优解,然后不断增大最小值(下限),每次在更新一下ans=min(ans,mx-mi)即可。

边界处理:j-1==0是或者cnt(取A的个数)==k+1时跳出循环。

总结:能直接用pair就直接用。优先队列:默认大顶堆,less大,greater小(直接试也可)。

代码:

#include <bits/stdc++.h>

#define ll long long
#define pi acos(-1)
#define pb push_back
#define mst(a, i) memset(a, i, sizeof(a))
#define pll pair<ll, ll>
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define rep(i, a, n) for (ll i = a; i <= n; i++)
#define per(i, n, a) for (ll i = n; i >= a; i--)
#define dbg(x) cout << #x << "===" << x << endl
#define dbgg(l, r, x) for(ll i=l;i<=r;i++)cout<<x[i]<<" ";cout<<"<<<"<<#x;cout<<endl
//多动脑,少动笔
using namespace std;

template<class T>void read(T &x){T res=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){res=(res<<3)+(res<<1)+c-'0';c=getchar();}x=res*f;}
void Printf(ll x){if(x<0){putchar('-');x=-x;}if(x>9)Printf(x/10);putchar(x%10+'0');}
void print(ll x,char c){Printf(x),putchar(c);}
const ll maxn = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll inf = 1e9;
#define plll pair<ll,pll >


ll cnt=0,ans=1e18,mx=0;
priority_queue<plll,vector<plll >,greater<plll> > q;
ll a[maxn][10],n,k;
void DBG(){
    while(!q.empty()){
        pair<ll,pll > now=q.top();q.pop();
        cout<<">>>"<<now.fi<<" "<<now.se.fi<<" "<<now.se.se<<'\n';
    }
}
int main()
{
    //freopen("testdata.in","r",stdin);
    //freopen("testout.out","w",stdout);
    ll TT=1;
    // read(TT);
    while(TT--){
        read(n),read(k);
        rep(i,1,n){
            rep(j,1,5){
                read(a[i][j]);
            }
            q.push({a[i][5],{i,5}});
            mx=max(mx,a[i][5]);
        }
        // DBG();
        ans=min(ans,mx-q.top().first);
        // dbg(ans);
        while(!q.empty()){
            ll k0,i=q.top().second.first,j=q.top().second.second;
            q.pop();
            // 
            if(j==1) break;
            if(j==2) cnt++;
            if(cnt==k+1) break;
            k0=a[i][j-1];
            mx=max(k0,mx);
            q.push({k0,{i,j-1}});
            ll k1=q.top().first;
            ans=min(ans,mx-k1);
            // dbg(mx),dbg(k1);
            // if(cnt==k) break;
        }
        print(ans,'\n');
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值