2019年湖南科技大学第7届大学生计算机程序设计竞赛E&&F

从这周开始就没课了也太爽了吧!
但是有三周的课设
咳咳咳在摸完🐟之后,又开始了苦逼的做题时间。
终于把EF肝完辣!
在这里插入图片描述
E:坏坏坏
思路:首先把符合条件的关卡存起来备用,不符合的当然就不管它啦。(也就是小唐可以闯关成功的),然后判断关数,如果等于0,则就特例输出。如果小于等于k,所以无论如何,所有关都要通过,于是就遍历找到 a m a x a_{max} amax b m a x b_{max} bmax,然后按得分规则计算。最难处理的就是关数大于k的情况了(想了我好久),可以将pair数组排序,然后通过优先队列把前k个push进去,但是要注意是,pair优先对列中,first位置放的是pair的second(因为我们枚举的是 a m a x a_{max} amax,所以要时刻得到 b m a x b_{max} bmax),然后不断维护 ( a m a x + b m a x ) m i n (a_{max}+b_{max})_{min} (amax+bmax)min

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for (int i=a;i<n;i++)
#define fi first
#define se second
using namespace std;
//head file
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ll n,k;
        cin>>n>>k;
        ll h,m;
        cin>>h>>m;
        vector<pair<ll,ll>>v;
        rep(i,0,n)
        {
            ll a,b;
            cin>>a>>b;
            if(a<=h&&b<=m)
                v.push_back(make_pair(a,b));
        }
        if(v.size()==0)
        {
            printf("0.000\n");
            continue;
        }
        sort(v.begin(),v.end());
        priority_queue<pair<ll,ll>>q;
        if(v.size()<=k)
        {
            ll am=-1;
            ll bm=-1;
            rep(i,0,v.size())
            {
                am=max(am,v[i].fi);
                bm=max(bm,v[i].se);
            }
            printf("%.3f\n",1000000000.0/(am+bm));
        }
        else
        {
            rep(i,0,k)
            {
                q.push(make_pair(v[i].se,v[i].fi));
            }
            ll ans=v[k-1].first+q.top().fi;
            for(int i=k;i<v.size();i++)
            {
                if(v[i].se<q.top().fi)
                {
                    q.pop();
                    q.push(make_pair(v[i].se,v[i].fi));
                }
                ans=min(ans,v[i].fi+q.top().fi);
            }
            printf("%.3f\n",1000000000.0/ans);
        }
    }
}

F:我有特殊的排序技巧
思路:因为每个数 a i a_{i} ai要等 a i a_{i} ai时间才会输出,所以在误差时间为0的情况下,总会输出从小到大的排序结果,但是造成的误差就是,某一个数可能提前,也可能延后,有个坑点是,当序列有相同的数(设为 n u m num num)时,他们会在同一个误差范围内输出,即 [ n u m − 2 , n u m + 2 ] [num-2,num+2] [num2,num+2],而且无论怎么输出,都是满足条件的。所以我们用unique函数进行去重。然后在不重复的数中,我们可以发现,要百分之百保证得到正确答案,所以相邻两个数的误差范围内,不能有交集,这就是判断的核心标准。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for (int i=a;i<n;i++)
using namespace std;
//head file
int main()
{
    int t;
    cin>>t;
    vector<ll>v;
    rep(i,0,t)
    {
        ll num;
        cin>>num;
        v.push_back(num);
    }
    sort(v.begin(),v.end());
    v.erase( unique( v.begin(),v.end() ) , v.end() );
    for(int i=0;i+1<v.size();i++)
    {
        if(v[i+1]-v[i]<=4)
        {
            cout<<"no"<<endl;
            return 0;
        }
    }
    cout<<"yes";
    return 0;
}

发现校赛还是很多思维题的,题干花里胡哨看能不能找到核心的思路了,E&&F就更新到这里啦,后面随缘更新校赛题和新生赛题(其实就是懒
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值