USACO历年青铜组真题解析 | 2023年12月Candy Cane Feast

学习C++从娃娃抓起!记录下USACO(美国信息学奥赛)备考青铜组别比赛学习过程中的题目,记录每一个瞬间。

附上汇总贴:USACO历年青铜组真题解析 | 汇总-CSDN博客


【题目描述】

农夫约翰(FJ)的奶牛非常喜欢吃甜食,尤其喜欢吃拐杖糖!FJ共有N头奶牛,每头奶牛都有一定的初始身高,他想喂养它们M根拐杖糖,每根拐杖糖也有不同的高度(1≤N,M≤2⋅105)。

FJ计划按照输入给出的顺序,一根接一根地把拐杖糖喂给奶牛。为了给他的奶牛喂食拐杖糖,他会把拐杖糖悬挂起来,让拐杖糖的底部刚好碰到地面。然后,奶牛们会按输入给出的顺序一个接一个地排队,走向拐杖糖,每只奶牛都会把自己高度所及的部分的拐杖糖吃掉(因为它们无法触及更高的部分)。即使在奶牛吃掉了底部的拐杖糖之后, 拐杖糖会仍然悬挂在最初竖立的地方,并不会下降到地面上。如果拐杖糖的底部已经高于某只奶牛的身高, 那么这只奶牛可能在轮到她时什么也不吃。在每头奶牛都吃了一次之后,奶牛的身高会随着它们吃了多少单位的拐杖糖而增长,并且农夫约翰会挂上下一根拐杖糖(底部仍然刚好碰到地面), 奶牛们再次重复此过程(11号奶牛再次第一个开始吃下一根拐杖糖)。

【输入】

第一行包含NM

第二行包含N头奶牛的初始身高,每个身高都在[1,10^9]的范围内。

第三行包含M根拐杖糖的高度,每个高度都在[1,10^9]的范围内。

【输出】

一共N行,每行一个数字,表示N头奶牛的最终身高。

【输入样例】

3 2
3 2 5
6 1

【输出样例】

7
2
7

【代码详解】

USACO历年青铜组真题解析 | 2023年12月Candy Cane Feast_第1张图片

#include 
using namespace std;
typedef long long ll;
int n, m;
ll a[200005];
struct node {
    int top, bottom;
}b[200005];
int main()
{
    cin >> n >> m;  // 输入n和m
    for (int i=1; i<=n; i++) {  // 输入n个奶牛的身高
        cin >> a[i];
    }
    for (int i=1; i<=m; i++) {  // 输入m个拐杖糖的高度
        cin >> b[i].top;  // 输入拐杖糖的高度
        b[i].bottom = 0;  // 同时记录该拐杖糖的底部为0
    }
    for (int i=1; i<=m; i++) {  // 先遍历m再遍历n(反过来会超时,部分测试点会TLE)
        for (int j=1; j<=n; j++) {  
            if (b[i].top==0) break;  // 如果该拐杖糖已经被吃掉了,则跳过该糖(就是通过该行代码减少了时间复杂度)
            if (a[j]<=b[i].bottom) continue;  // 如果奶牛高度小于糖的底部高度,则说明没法吃到,继续循环
            if (a[j]>=b[i].bottom && a[j]=b[i].top) {  // 如果奶牛比糖的top位置还高
                a[j] = a[j] + (b[i].top-b[i].bottom);  // 则奶牛高度增加糖的长度(top-bottom)
                b[i].top = 0;  // 将糖的top修改为0,即被吃掉
            }
        }
    }
    for (int i=1; i<=n; i++) {  // 输出所有奶牛高度
        cout << a[i] << endl;
    }
    return 0;
}

【运行结果】

3 2
3 2 5
6 1
7
2
7

你可能感兴趣的:(算法,数据结构,c++)