2020 年百度之星·程序设计大赛 - 初赛一
[toc]

6743 Drink

题解:

每一种饮料求一个卡路里,取最小值
第一看以为是背包,其实出题人在第二层

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int dp[10005];
inline int read() {
    char ch = getchar(); 
    int x = 0, f = 1;
    while(ch < '0' || ch > '9') {
        if(ch == '-') f = -1;
        ch = getchar();
    } while('0' <= ch && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    } return x * f;
}
int main()
{
    int t,e,f,m,n,pi,wi;
    t=read();
    while(t--)
    {
        scanf("%d%d",&n,&m);
        //m=read();
        int sum=10000;
        for(int i=1;i<=n;i++)                     
        {
            wi=read();
            pi=read();
            int a;
             if(m%wi==0)a=m/wi;
             else a=m/wi+1;
            sum=min(a*pi,sum);
        }

            printf("%d\n",sum);

        //cout<<dp[m]<<endl;
    }
    return 0;
} 

6744 GPA

题解:

给的一个分数范围,我们要让分数总和最高,就要找怎么给四个成绩赋分最有价值。一个分数区间对应的绩点是一样的,那我们就取分数区间的最低分即可,[95,100]都对应4.3,那我们就取95就行
具体做法我是这样的,用一个数组来村每个区间的最小数,用另一数组来存每个区间最小数对应的绩点,然后四个for循环暴力完事

代码:

#include<iostream>
#include<cstdio>
using namespace std;
double a[104];
int b[]={0,0,60,62,65,67,70,75,80,85,90,95};
void init()
{
    a[0]=0;a[60]=1.0;a[62]=1.7;a[65]=2.0;a[67]=2.3;a[70]=2.7;a[75]=3.0;
    a[80]=3.3;a[85]=3.7;a[90]=4.0;a[95]=4.3;

}
int main()
{
    int t;
    init();
    scanf("%d",&t);
    while(t--)
    {
        double sum=0;
        int x;
        scanf("%d",&x);
        for(int i=1;i<=11;i++)
        {
            for(int j=1;j<=11;j++)
            {
                for(int k=1;k<=11;k++)
                {
                    for(int w=1;w<=11;w++)
                    {
                        if(b[i]+b[j]+b[k]+b[w]<=x)
                        {
                            double ans=a[b[i]]+a[b[j]]+a[b[k]]+a[b[w]];
                            if(ans>sum)sum=ans;
                        }
                    }
                }
            }
        }
        printf("%.1f\n",sum);
    }
}

6745 Dec

题解:

对于a和b,a和b的答案一定是在a-1,b或者a,b-1的基础上来的,如果a和b本身是互质则在前面的基础上+1,否则不加。
所以dp递推就行
看看数据,所以dp要预处理,然后直接输出答案

代码:

#include<iostream>
#include<cstdio>
#include <bitset>
using namespace std;
bitset<10000010> g;
int n,m,x,dp[1004][1005],top=0;
int gcd(int a,int b)
{
    if(b==0)return a;
    else return gcd(b,a%b);
}

int main()
{
    int t;
    scanf("%d",&t);
        for(int i=1;i<=1002;i++)
        for(int j=1;j<=1002;j++)
        {
            if(dp[i][j])continue;
            dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            if(gcd(i,j)==1)dp[i][j]++;
        }
    while(t--)
    {
        int a,b;
        scanf("%d%d",&a,&b);

        printf("%d\n",dp[a][b]); 
    }
}

6746 Civilization

6747 Rotate

6748 Matrix

6749 Mosquito

6750 Function