Codeforces Round #622(Div.2)

30 篇文章 0 订阅

A题:

题意:三种食物有个数限制,上菜,每次上菜跟以前的样式不能一样(食物的种类及个数各不相同),且每种食物最多用一次,问最多能上几次。
思路:这道题的话,对a,b,c排序,然后枚举上菜种类就可以了,注意最多能上7盘菜。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
int a[5];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        for(int i=1; i<=3; i++)
            cin>>a[i];
        int ans=0;
        for(int i=1; i<=3; i++)
            if(a[i])
            {
                a[i]--;
                ans++;
            }
        sort(a+1,a+4);
        if(a[2] && a[3])
        {
            a[2]--;
            a[3]--;
            ans++;
        }
        if(a[1] && a[3])
        {
            a[1]--;
            a[3]--;
            ans++;
        }
        if(a[1] && a[2])
        {
            a[1]--;
            a[2]--;
            ans++;
        }
        if(a[1] && a[2] && a[3])
        {
            ans++;
        }
        cout<<ans<<endl;
    }
    return 0;
}


B题:

题意:有n个人参加比赛,比赛分为两轮,每一轮均不会出现并列名次的情况,每个人最后得分为两轮排名之和,分数越小排名越高(会出现并列的情况)。现已知某人第一、二轮排名,问此人(以下称为A)排名最高最低分别为多少。
思路:这道题的话,最坏情况非常简单,显然为min(n, x+y-1),难点在于最好情况的推导。如果我们希望某人排名比A低,那么最优做法就是让某人分数为x+y+1。
此时我们需要分类讨论:
如果x+y<=n,那么对于其他人,若第一场排名为p,必然能让其在第二场排名为x+y+1-p甚至更高,从而使得其最终排名变低,此时A的排名为第一名。
如果x+y>n,那么对于其他人,若第一场排名为p,则让其第二场排名也为p,这样就能使得本身排名靠前的人继续靠前,这样我们就能忽略掉这个人,剩下的人就变成了一个规模小一点的子问题,而且剩下的人相对排名也会变小。重复这个过程直到x+y<=n,就变成了刚刚熟悉的场景,可以轻松解决。假设我们让t个人两轮排名相同,那么显然有x-t+y-t=n-t, t=x+y-n,此时A的排名一定为x+y-n+1。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,x,y;
        cin>>n>>x>>y;
        if(x+y<n)
            cout<<"1"<<" "<<min(x+y-1,n)<<endl;
        else
            cout<<min(x+y-n+1,n)<<" "<<min(x+y-1,n)<<endl;
    }
    return 0;
}


C1题:

题意:有n块地,我们要建造n个大楼,然后建造大楼有条件,一个大楼的左边和右边不能都比它高,问你满足条件的大楼的楼层数 。
思路:这道题的话,对于每一个i,i左边的位置定义为j,i右边的位置定义为k。要使得aj>ai<ak。我们可以画一下,要满足这一条件,就会使得这一串为一个“波”形。由于数据很小,我们直接暴力找答案即可。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=1010;
const int inf=0x3f3f3f3f;
using namespace std;
int a[maxx],b[maxx],c[maxx];
int main()
{
    int n;
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
        c[i]=a[i];
    }
    ll ans=0;
    for(int j=1; j<=n; j++)
    {
        int cnt=j;
        for(int i=cnt-1; i>=1; i--)
            if(a[i]>a[i+1])
                a[i]=a[i+1];
        for(int i=cnt+1; i<=n; i++)
            if(a[i]>a[i-1])
                a[i]=a[i-1];
        ll sum=0;
        for(int i=1; i<=n; i++)
            sum+=a[i];
        if(sum>ans)
        {
            ans=sum;
            for(int i=1; i<=n; i++)
                b[i]=a[i];
        }
        for(int i=1; i<=n; i++)
            a[i]=c[i];
    }
    for(int i=1; i<=n; i++)
        cout<<b[i]<<" ";
    cout<<endl;
    return 0;
}

 

C2题:单独写一下题解。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值