Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3)

点击打开链接

A.水题 题意开始有些迷

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,s;
    scanf("%d%d",&n,&s);
    int last=0,next;
    bool flag=false;
    for(int i=0;i<n;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        next=a*60+b;
        if(next-last>=s+1) {
                flag=true;
        }
        if(flag) continue;
        last=next+1+s;
    }
    printf("%d %d\n",last/60,last%60);
    return 0;
}

B.优先队列 注意边界条件的考虑

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,A,B,S1,pos=0;
    priority_queue<int>pq;
    while(!pq.empty()) pq.pop();
    scanf("%d%d%d",&n,&A,&B);
    for(int i=0;i<n;i++)
    {
        int s;
        scanf("%d",&s);
        if(i==0) S1=s;
        else pq.push(s);
        pos+=s;
    }
    int ans=0,m=S1*A/B,k=pos-m,cnt=0;
    while(!pq.empty())
    {
		if(cnt>=k) {
            break;
        }
        int p=pq.top();
        pq.pop();
        cnt+=p;
        ans++;
    }
    cout<<ans<<endl;
    return 0;
}

C.二分查找 思维题

思路:依次枚举左边的第一个楼梯 左边的第一个电梯 右边的第一个楼梯 右边的第一个电梯 使用这四种方式转移 取得最小值

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const int INF=0x3f3f3f3f;
int stairs[maxn],eve[maxn];
int main()
{
    int n,m,cl,ce,v;
    scanf("%d%d%d%d%d",&n,&m,&cl,&ce,&v);
    //二分查找左边的第一个楼梯 左边的第一个电梯 右边的第一个楼梯 右边的第一个电梯
    for(int i=0;i<cl;i++)
        scanf("%d",&stairs[i]);
    for(int i=0;i<ce;i++)
        scanf("%d",&eve[i]);
    int q;
    scanf("%d",&q);
    while(q--)
    {
        int x1,y1,x2,y2,solve=INF;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        if(x1==x2) solve=abs(y1-y2);
        else {
            int t=abs(x1-x2);
            int p1=lower_bound(stairs,stairs+cl,y1)-stairs;
            int p2=lower_bound(eve,eve+ce,y1)-eve;
            if(p1==0) {
                if(stairs[p1]==y1) {
                    solve=min(solve,t+abs(y1-y2));
                }
            }
            else {
                if(stairs[p1]==y1) {
                    solve=min(solve,t+abs(y1-y2));
                }
                else {
                    solve=min(solve,y1-stairs[p1-1]+t+abs(y2-stairs[p1-1]));
                }
            }
            if(p1<cl) {
                solve=min(solve,stairs[p1]-y1+t+abs(y2-stairs[p1]));
            }
            if(p2==0) {
                if(eve[p2]==y1) {
                    solve=min(solve,(t%v?t/v+1:t/v)+abs(y1-y2));
                }
            }
            else {
                if(eve[p2]==y1) {
                    solve=min(solve,(t%v?t/v+1:t/v)+abs(y1-y2));
                }
                else {
                    solve=min(solve,y1-eve[p2-1]+(t%v?t/v+1:t/v)+abs(y2-eve[p2-1]));
                }
            }
            if(p2<ce) {
                solve=min(solve,eve[p2]-y1+(t%v?t/v+1:t/v)+abs(y2-eve[p2]));
            }
        }
        printf("%d\n",solve);
    }
    return 0;
}

D.贪心 具体思路详见下面这个博客:https://blog.csdn.net/finalcsdn/article/details/80184035,是个挺麻烦的贪心

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=3e5+5;
struct node{
int num,id;
};
bool cmp(node a,node b)
{
    return a.num<b.num;
}
int main()
{
    int n,x1,x2;
    node c[maxn];
    scanf("%d%d%d",&n,&x1,&x2);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&c[i].num);
        c[i].id=i;
    }
    sort(c+1,c+1+n,cmp);                        //从小到大排序
    //先满足x1 再满足x2
    for(int i=1;i<=n;i++)
    {
        //从i开始向前取k1个数
        int k1=x1%c[i].num?x1/c[i].num+1:x1/c[i].num;
        if(i+k1>n) continue;
        int k2=x2%c[i+k1].num?x2/c[i+k1].num+1:x2/c[i+k1].num;
        if(i+k1+k2>n+1) continue;
        printf("Yes\n%d %d\n",k1,k2);
        for(int j=i;j<i+k1;j++)
            printf("%d ",c[j].id);
        printf("\n");
        for(int j=i+k1;j<i+k1+k2;j++)
            printf("%d ",c[j].id);
        printf("\n");
        return 0;
    }
    //先满足x2,再满足x1
    for(int i=1;i<=n;i++)
    {
        //从i开始向前取k1个数
        int k1=x2%c[i].num?x2/c[i].num+1:x2/c[i].num;
        if(i+k1>n) continue;
        int k2=x1%c[i+k1].num?x1/c[i+k1].num+1:x1/c[i+k1].num;
        if(i+k1+k2>n+1) continue;
        printf("Yes\n%d %d\n",k2,k1);
        for(int j=i+k1;j<i+k1+k2;j++)
            printf("%d%c",c[j].id,j==i+k1+k2?'\n':' ');
        printf("\n");
        for(int j=i;j<i+k1;j++)
            printf("%d ",c[j].id);
        printf("\n");
        return 0;
    }
    printf("No\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37428263/article/details/80252001
今日推荐