Codeforces Round #477 (rated, Div. 2)

题目链接: Codeforces Round #477

A. Mind the Gap
题目大意:有n个着陆时间,现在要你去插入一个起飞时间,着陆和起飞都需要一分钟,并且插入之后所有的起飞和着陆时间之间的时间差至少得为s,问能插入的最早的时间点是多少

题目思路:直接排完序之后贪心去找就好了,时间差应当在s+1之外,特判一下第一次之前和最后一次着陆时间就好了

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;

int n,s;
struct node{
    int h,m;
}time[105];

bool cmp(node a,node b){
    if(a.h == b.h) return a.m < b.m;
    return a.h < b.h;
}

int main(){
    scanf("%d%d",&n,&s);
    for(int i = 0;i < n;i++) scanf("%d%d",&time[i].h,&time[i].m);
    sort(time,time+n,cmp);
    for(int i = 0;i < n;i++){
        if(i == 0){
            if(1+s <= time[i].h*60+time[i].m) {printf("0 0\n");break;}
        }
        if(i == n-1){
            int tim = time[i].h*60+time[i].m+1+s;
            printf("%d %d\n",tim/60,tim%60);break;
        }
        else if(i!= n-1){
            int tim = time[i].h*60+time[i].m+1+s;
            if(tim+s+1 <= time[i+1].h*60+time[i+1].m) {printf("%d %d\n",tim/60,tim%60);break;}
        }
    }
    return 0;
}

B. Watering System
题目大意:有n个水坑,每个坑有一个容量si,现在有A升的水,现在你要去填一些坑,这些坑就可以不共享水了,问最少填几个坑能使得第一个坑的水达到B升,每个坑的水为si*A/S,S为剩下没被填上的坑的容量和

题目思路:对除第一个坑外的其他坑按容量从大到小填就好了

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;
typedef long long ll;
const ll maxn = 1e5+10;

ll n,A,B,si[maxn],sum,intal;

int main(){
    scanf("%I64d%I64d%I64d",&n,&A,&B);
    scanf("%I64d",&intal);
    sum = intal;
    for(ll i = 0;i < n-1;i++){
        scanf("%I64d",&si[i]);
        sum += si[i];
    }
    if(intal*A >= B*sum) {puts("0");return 0;}
    sort(si,si+n-1);
    ll num = 0;
    for(ll i = n-2;i >= 0;i--){
        sum -= si[i];
        num++;
        if(intal*A >= B*sum) {printf("%I64d\n",num);break;}
    }
    return 0;
}

C. Stairs and Elevators
题目大意:有一个n层的楼层,每层m个房间,假想为n行m列的矩阵,某一些列有电梯或者楼梯,楼梯一秒走1层,电梯一秒最多走V层,同层之间房间走是一秒一个房间,给定起点和终点,问最少多少秒能到

题目思路:我们可以直接贪心做这样一个东西,一定是不存在即走楼梯又走电梯这种方式的,这样并不能节省时间,然后如果起点和终点之间的列之间有电梯或楼梯,那么我们直接走电梯或者楼梯就好了,如果没有的话,就去两边找最近的楼梯和电梯,实际上我们找到列数较小的左右两端最近的楼梯电梯然后比较就好了,注意一个小trick就是同层之间不用找电梯或楼梯,直接算就好了


#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;
typedef long long ll;
const ll maxn = 1e5+10;
const ll INF = 1e18+10;

ll n,m,cl,ce,v;
ll stair[maxn],elevator[maxn];
ll q,sth,stl,enh,enl;
ll ans1,ans2;

int main(){
    scanf("%I64d%I64d%I64d%I64d%I64d",&n,&m,&cl,&ce,&v);
    for(ll i = 0;i < cl;i++) scanf("%I64d",&stair[i]);
    for(ll i = 0;i < ce;i++) scanf("%I64d",&elevator[i]);
    sort(stair,stair+cl);
    sort(elevator,elevator+ce);
    scanf("%I64d",&q);
    while(q--){
        ans1 = INF,ans2 = INF;
        scanf("%I64d%I64d%I64d%I64d",&sth,&stl,&enh,&enl);
        if(sth == enh) {printf("%I64d\n",abs(enl-stl));continue;}
        ll se1,se2;
        if(cl != 0){
            if(enl <= stl) {
                if(stair[cl-1] < enl) se1 = stair[cl-1],se2 = stair[cl-1];
                else {
                    se1 = stair[lower_bound(stair,stair+cl,enl)-stair];
                    if(se1 == stair[0]) se2 = se1;
                    else se2 = stair[lower_bound(stair,stair+cl,enl)-stair-1];
                }
            }
            else{
                if(stair[cl-1] < stl) se1 = stair[cl-1],se2 = stair[cl-1];
                else {
                    se1 = stair[lower_bound(stair,stair+cl,stl)-stair];
                    if(se1 == stair[0]) se2 = se1;
                    else se2 = stair[lower_bound(stair,stair+cl,stl)-stair-1];
                }
            }
            ans1 = abs(stl-se1)+abs(sth-enh)+abs(se1-enl);
            ans1 = min(ans1,abs(stl-se2)+abs(sth-enh)+abs(se2-enl));
        }
        if(ce != 0){
            if(enl <= stl) {
                    if(elevator[ce-1] < enl) se1 = elevator[ce-1],se2 = elevator[ce-1];
                    else {
                        se1 = elevator[lower_bound(elevator,elevator+ce,enl)-elevator];
                        if(se1 == elevator[0]) se2 = se1;
                        else se2 = elevator[lower_bound(elevator,elevator+ce,enl)-elevator-1];
                    }
            }
            else {
                if(elevator[ce-1] < stl) se1 = elevator[ce-1],se2 = elevator[ce-1];
                else{
                    se1 = elevator[lower_bound(elevator,elevator+ce,stl)-elevator];
                    if(se1 == elevator[0]) se2 = se1;
                    else se2 = elevator[lower_bound(elevator,elevator+ce,stl)-elevator-1];
                }
            }
            ll xx;
            if((abs(sth-enh)) % v == 0ll) xx = (abs(sth-enh))/v;
            else xx = (abs(sth-enh))/v+1;
            ans2 = abs(stl-se1)+abs(xx)+abs(se1-enl);
            ans2 = min(ans2,abs(stl-se2)+abs(xx)+abs(se2-enl));
        }
        printf("%I64d\n",min(ans1,ans2));
    }
    return 0;
}

D. Resource Distribution
题目大意:有n台服务器,每台服务器有最大承受度ci,然后有两台机房,需要x和y容量,他们的容量分均分到服务器台数上,比如8,分配给了他2台服务器,每台服务器的ci至少得为4,问能不能分配一些(not all)服务器给机房使得满足条件

题目思路:贪心去做,最大到小尝试分配给服务器就好了,具体看代码



#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;
typedef long long ll;
const ll maxn = 4e5+10;

ll n,x1,x2;
ll num1,num2;
bool flag1,flag2;
vector<ll>v1,v2;

struct node{
    ll val,num;
}c[maxn];

bool cmp(node a,node b){
    return a.val > b.val;
}

int main(){
    scanf("%I64d%I64d%I64d",&n,&x1,&x2);
    for(ll i = 1;i <= n;i++) scanf("%I64d",&c[i].val),c[i].num = i;
    sort(c+1,c+n+1,cmp);
    v1.clear();v2.clear();
    num1 = num2 = 0;
    flag1 = flag2 = false;
    ll i;
    for(i = 1;i <= n;i++){
        num2++;
        v2.push_back(c[i].num);
        if(x2 <= num2*c[i].val) {flag2 = true;break;}
    }
    for(ll j = i+1;j <= n;j++){
        num1++;
        v1.push_back(c[j].num);
        if(x1 <= num1*c[j].val) {flag1 = true;break;}
    }
    if(flag1&&flag2) {
        puts("Yes");
        printf("%I64d %I64d\n",num1,num2);
        printf("%I64d",v1[0]);
        for(i = 1;i < num1;i++) printf(" %I64d",v1[i]);
        puts("");
        printf("%I64d",v2[0]);
        for(i = 1;i < num2;i++) printf(" %I64d",v2[i]);
        puts("");
        return 0;
    }
    else{
        v1.clear();v2.clear();
        num1 = num2 = 0;
        flag1 = flag2 = false;
    }
    for(i = 1;i <= n;i++){
        num1++;
        v1.push_back(c[i].num);
        if(x1 <= num1*c[i].val) {flag1 = true;break;}
    }
    for(ll j = i+1;j <= n;j++){
        num2++;
        v2.push_back(c[j].num);
        if(x2 <= num2*c[j].val) {flag2 = true;break;}
    }
    if(flag1&&flag2) {
        puts("Yes");
        printf("%I64d %I64d\n",num1,num2);
        printf("%I64d",v1[0]);
        for(i = 1;i < num1;i++) printf(" %I64d",v1[i]);
        puts("");
        printf("%I64d",v2[0]);
            for(i = 1;i < num2;i++) printf(" %I64d",v2[i]);
            puts("");
    }
    else puts("No");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值