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