2020百度之星程序设计比赛初赛第一场(一)

看了各位大神的代码,结合了大神们的算法思想和我的一点小改动,以下算是题解吧,大家可以稍作参考!

Drink

Problem Description

我们有 n种不同的饮料,每种饮料有无限多瓶,第 i 种饮料一瓶提供 x[i]毫升的水分,包含 y[i] 卡路里。现在我们需要选择一种饮料一直喝,直到补充了至少 m 毫升的水分,我们想使得摄入的卡路里总和最小。请求出这个最小值。一旦打开一瓶饮料,就一定要喝完。

Input

第一行一个整数 test(1 <= test <= 100)表示数据组数。
对于每组数据,第一行两个整数 n,m(1≤n≤100,1≤m≤10000)。
接下来 n 行,每行两个整数 x[i],y[i] (1≤x[i],y[i]≤100)。

Output

对于每组数据,一行一个整数表示答案。

Sample Input

2
1 10
3 3
2 10
3 3
2 1

Sample Output

12
5
#include <iostream>
using namespace std;
int main()
{
	int test,n,m,x,y;
	cin >> test;
	while(test--){
		cin >> n >> m;
		int min = 99999999;
		for(int i=0;i<n;i++)
		{
			cin >> x >> y;
			int t,temp= m /x;
			if(temp * x != m)
				temp++;
			t = temp * y;
			if(t < min)
				min = t;
		}
		cout << min << endl;
	}
	return 0;
} 

GPA

Problem Description

小沃沃一共参加了 4 门考试,每门考试满分 100 分,最低 0 分,分数是整数。
给定四门考试的总分,请问在最优情况下,四门课绩点的和最高是多少?
分数与绩点之间的对应关系如下:
95~100 4.3
90~94 4.0
85~89 3.7
80~84 3.3
75~79 3.0
70~74 2.7
67~69 2.3
65~66 2.0
62~64 1.7
60~61 1.0
0~59 0

Input

第一行一个正整数test(1≤test≤401) 表示数据组数。 接下来 test行,每行一个正整数 x 表示四门考试的总分 (0≤x≤400)。

Output

对于每组数据,一行一个数表示答案。答案保留一位小数。

Sample Input

2
0
400

Sample Output

0.0
17.2
#include <iostream>
#include <cmath>
using namespace std;
int x[]={0,60,62,65,67,70,75,80,85,90,95,500};
int sum[]={0,10,17,20,23,27,30,33,37,40,43,-1000};
int dfs(int a,int s)
{
    if (s==1)
    {
        if (a>=95)    return 43;
        if (a>=90)    return 40;
        if (a>=85)    return 37;
        if (a>=80)    return 33;
        if (a>=75)    return 30;
        if (a>=70)    return 27;
        if (a>=67)    return 23;
        if (a>=65)    return 20;
        if (a>=62)    return 17;
        if (a>=60)    return 10;
        return 0;
    }

    int ans=0;
    for (int i=1;x[i]<=a;i++)
    {
        ans=max(ans,sum[i]+dfs(a-x[i],s-1));
    }
    return ans;
}
int main()
{
    int t,a;
    scanf ("%d",&t);
    for (int i=1;i<=t;i++)
    {
        scanf ("%d",&a);
        int x=dfs(a,4);
        printf("%d.%d\n",x/10,x%10);
    }
    return 0;
}

Dec

Problem Description

初始有 a, b 两个正整数,每次可以从中选一个大于 1 的数减 1,最后两个都会减到 1,我们想知道在过程中两个数互质的次数最多是多少。

Input

第一行一个正整数 test(1≤test≤1000000) 表示数据组数。
接下来 test 行,每行两个正整数 a,b(1≤a,b≤1000)。

Output

对于每组数据,一行一个整数表示答案。

Sample Input

1
2 3

Sample Output

4
样例解释
2 3 -> 1 3 -> 1 2 -> 1 1
#include<bits/stdc++.h>
using namespace std;
#define ll long long

const int N = 1005;
int T, f[N][N];
int main() {
    for(int i=1; i<=1000; ++i) 
		for(int j=1; j<=1000; ++j)
        	f[i][j]=max(f[i][j-1], f[i-1][j])+(__gcd(i, j)==1);
    scanf("%d", &T);
    while(T--){
        int x, y;
        scanf("%d%d", &x, &y);
        printf("%d\n", f[x][y]);
    }
    return 0;
}

Civilization

Problem Description

这是一个回合制游戏,每一回合开始前会进行上一回合的结算。
有一张 n∗n 的棋盘,我们出生在一个初始位置(x,y),现在我们要选择一个位置建设城市。
你的人物每回合可以移动到距离你曼哈顿距离不超过 2 的位置,移动完成后可以选择是否建立城市。
建立城市后,你的人物消失,成为一个人口为 1 的城市,这个人口要下回合才可以工作。如果不移动,直接在 (x,y) 建城,第 1 回合就可以开始工作。
对于城市的每个居民,你可以安排他到距离城市曼哈顿距离小于等于 3 的位置进行工作,此居民可以瞬间到达该位置,每个位置最多安排一个居民,失业的人口不会生产任何食物。
注意,城市位置上必须有一个居民在工作。
结算按照如下顺序:
如果位置 (i,j) 上有一个工作居民,则获得 a[i] [j] 的食物。
如果当前城市人口为 i,且食物达到 8*i^2时,你获得一个新的居民,下一回合可以进行操作。
当结算后城市总人口达到 9 游戏结束。
初始食物数量为 0,人口上涨不会导致之前积累的食物消失。输出最少几个回合能让游戏结束。

Input

第一行一个正整数 test(1≤test≤10) 表示数据组数。
对于每组数据,第一行三个正整数n(2≤n≤500),x(1≤x≤n),y(1≤y≤n),分别表示棋盘大小和起始位置。
接下来 n 行,每行 n 个整数,第 i 行第 j 列的整数表示 a[i] [j] (1≤a[i] [j]≤3)。

Output

对于每组数据,一行一个整数表示答案。

Sample Input

1
10 9 8
1 2 2 1 2 3 1 1 2 1
2 1 3 3 3 2 3 2 3 1
1 1 3 1 1 3 2 2 1 2
3 1 3 1 3 3 1 3 1 3
3 2 3 1 3 1 2 2 2 1
2 3 2 3 2 2 3 1 2 3
3 1 3 3 2 2 3 2 3 3
1 3 3 2 3 2 2 2 1 1
3 3 1 2 3 2 1 2 1 2
1 1 3 1 3 1 1 1 3 3

Sample Output

39
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 7;

int n , x , y , a[501][501];

int judge(int x,int y){
    if(x>=1 && x<=n && y>=1 && y<=n) return 1;
    return 0;
}

int Solve(int x,int y){
    int Tong[4] = {0};
    for(int i = max(1,x-3);i<=min(n,x+3);i++){
        for(int j=max(1,y-3);j<=min(n,y+3);j++){
            if(abs(i-x) + abs(j-y) <= 3){
                Tong[a[i][j]] ++;
            }
        }
    }
    int ans = 0 , Food = 0 , Power = a[x][y];
    Tong[a[x][y]] --;
    for(int i=1;i<=8;i++){
        int x = max(0 , (8*i*i - Food + Power - 1) / Power);
        ans += x;
        Food += x * Power;
        for(int j=3;j>=1;j--){
            if(Tong[j]){
                Power += j;
                Tong[j] --;
                break;
            }
        }
    }
    return ans;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&n,&x,&y);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&a[i][j]);
            }
        }
        int ans = 1e9 + 7;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                int Time = (abs(i-x) + abs(j-y) + 1) / 2 + Solve(i,j);
                ans = min(ans , Time);
            } 
        }
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不能say的秘密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值