USACO 2022 Cu 题解

AK用时:$ 3 $ 小时 $ 30 $ 分钟。

A - Cow College

原题

Farmer John 计划为奶牛们新开办一所大学!

有 $ N $($ 1 \le N \le 10^5 $) 头奶牛可能会入学。每头奶牛最多愿意支付 $ c_i $ 的学费($ 1 \le c_i \le 10^6 $)。Farmer John 可以设定所有奶牛入学需要支付的学费。如果这笔学费大于一头奶牛愿意支付的最高金额,那么这头奶牛就不会入学。Farmer John 想赚尽可能多的钱,从而可以给他的讲师提供一笔可观的工资。请求出他能赚到的钱的数量,以及此时应当收取多少学费。

思路

本题其实很简单,首先我们一上来会想到从 $ 1 $ 枚举到所有 $ c_i $ 里的最大值 $ Max $。但是其实是不可行的,会超时。

然后我们稍加考虑,就会发现,我们只需要枚举奶牛的学费 $ c_i $ 就可以了。为什么?因为奶牛只会支付小于 $ c_i $ 的学费,一旦大于,无论怎么调都不会有所变化。所以枚举学费。举个例子,若 $ c_i $ 为 `2 6` ,当学费为 $ 3 $ 或 $ 4 $,都只会有一头奶牛交钱。这种时候,只考虑最大值 $ 6 $ 即可。复杂度 $ O(n^2) $。

但是好像还会超时,所以我们继续考虑优化。我们首先可以将所有的 $ c_i $ 排序,然后就会发现,其实重复的值我们直接跳过即可。继续优化,当我们枚举到 $ c_i $ 时,$ c_i $ 前面的值一定不可取,直接跳过,也就是说计算总钱数的时候,我们直接从 $ i $ 开始枚举即可。其实这样就可以过了。我们也可以继续优化。由于现金又是一样的,我们可以用乘法代替循环,即 $ (n - i + 1) \times c_i $。复杂度 $ O(n) $。

赛时代码

# include <bits/stdc++.h>

# define int long long

using namespace std;

int n, c[100005];

signed main () {

    cin >> n;

    int sum = -114514;

    for (register int i = 1; i <= n; ++ i) {

        cin >> c[i];

        sum = max (sum, c[i]);

    }

    int ans = 0, ansi = 0;

    sort (c + 1, c + 1 + n);

    for (register int i = 1; i <= n; ++ i) {

        int nw = 0;

        for (register int j = i; j <= n; ++ j) {

            nw += c[i];

        }

        if (nw > ans) ans = nw, ansi = c[i];

    }

    cout << ans << " " << ansi << endl;

    return 0;

}

赛后优化代码

# include <bits/stdc++.h>

# define int long long

using namespace std;

int n, c[100005];

signed main () {

    cin >> n;

    int sum = -114514;

    for (register int i = 1; i <= n; ++ i) {

        cin >> c[i];

        sum = max (sum, c[i]);

    }

    int ans = 0, ansi = 0;

    sort (c + 1, c + 1 + n);

    for (register int i = 1; i <= n; ++ i) {

        int nw = (n - i + 1) * c[i];

        if (nw > ans) ans = nw, ansi = c[i];

    }

    cout << ans << " " << ansi << endl;

    return 0;

}

B - Feeding the Cows

原题

Farmer John 有 $ N $($ 1 \le N \le 10^5 $)头奶牛,每头奶牛的品种是更赛牛(Guernsey)或荷斯坦牛(Holstein)之一。她们沿水平方向排成一行,奶牛们占据的位置编号为 $ 1…N $。
由于奶牛们都饿了,FJ 决定在 $ 1…N $ 中的某些位置上种植草地。更赛牛和荷斯坦牛喜欢不同类型的草,所以如果 Farmer John 决定在某个位置种草,他必须选择种植更赛牛喜欢的草或荷斯坦牛喜欢的草——他不能在同一个位置同时种两种草。种植的每一片草地都可以喂饱数量不限的相应品种的奶牛。

每头奶牛愿意移动至多 $ K $($ 0 \le K \le N - 1 $)个位置以前往一个草地。求出喂饱所有奶牛所需种植的最小草地数量。此外,输出一种使用最小草地数量喂饱所有奶牛的种植方案。任何满足上述条件的方案均视为正确。

思路

朴素思路:枚举全排列,会死的很惨。

我们不妨考虑贪心,为了让一片草能养活尽可能多的奶牛,我们要把草种到离它尽量远又能让它吃到的位置。那我们就可以从可以放的位置最远开始枚举,一直枚举到自己,甚至自己之后。那范围就是从 $ i + k $ 到 $ i - k $。从远到近,发现没有种的地方,就种上。然后共这棵草开始枚举,在这个草能影响到的范围,将同种牛标记一下,这头牛就不用刻意种草了。

复杂度大概是 $ O(nk) $。

(赛时)代码

# include <bits/stdc++.h>

# define rep(i, a, b) for (register int (i) = (a); (i) <= (b); ++ (i))

# define per(i, a, b) for (register int (i) = (a); (i) >= (b); -- (i))

using namespace std;

const int N = 10000005;

int T;

int n, k;

bool vis[N];

char ans[N];

string s;

signed main () {

    cin >> T;

    while (T --) {

        cin >> n >> k >> s;

        rep (i, 0, n - 1) vis[i] = 0, ans[i] = '.';

        int answ = 0;

        rep (i, 0, n - 1) {

            if (vis[i]) continue;

            int nw = i;

            per (j, min (i + k, n - 1), max (i - k, 0))

                if (ans[j] == '.') { ans[j] = s[i]; nw = j; break; }

            rep (j, i, min (k + nw, n - 1)) if (s[j] == s[i]) vis[j] = 1;

            ++ answ;

        }

        cout << answ << endl;

        rep (i, 0, n - 1) putchar (ans[i]);

        putchar ('\n');

    }

    return 0;

}

C - Reverse Engineering

原题

Elsie 有一个程序,接受一个 $ N $($ 1≤N≤100 $)个变量的数组 $ b[0],...,b[N - 1] $ 作为输入,其中每个变量等于 $ 0 $ 或 $ 1 $,并且返回对输入数组应用一系列 if / else if / else 语句的结果。每个语句检查至多一个输入变量的值,并返回 $ 0 $ 或 $ 1 $。这类程序的一个例子是:

if (b[1] == 1) return 1;
else if (b[0] == 0) return 0;
else return 1;

例如,如果上方程序的输入是 "10"(即 $ b[0]=1 $ 及 $ b[1]=0 $),那么输出应当为 $ 1 $。

Elsie 告诉了 Bessie 对于 $ M $($ 1≤M≤100 $)个不同输入的正确输出。Bessie 现在正试图对 Elsie 的程序进行逆向工程。不幸的是,Elsie 可能说了谎;可能不存在上述形式的程序行为与 Elsie 所说的均一致。

对于 $ T $($ 1≤T≤10 $)个子测试用例中的每一个,判断 Elsie 是否一定在说谎,如果是,就输出 `LIE`,否则输出 `OK`。

思路

这道题也是重磅题了。

首先我们假设他是对的,我们要找错误的地方,首先我们循环,对于每个数组 $ b $,我们要先找为 $ 0 $ 的,看看输出的结果一不一样。如果一样,说明判断的点在这个 $ b_i $。直接把所有为 $ 0 $ 的打标记送走即可。否则接着枚举。找完 $ 0 $,找 $ 1 $ 即可。如果所有的都打完标记了,就输出 `OK`,如果发现一个标记都没打,就直接输出 `LIE`,因为再循环下去就是死循环了。复杂度大概是 $ O(Tnm) $。

好像这道题还可以暴力,复杂度还要高,但是可以过去。暴力的代码我不太会写,就先等着吧QwQ。

(赛时)代码

# include <bits/stdc++.h>

# define rep(i, a, b) for (register int (i) = (a); (i) <= (b); ++ (i))

# define per(i, a, b) for (register int (i) = (a); (i) >= (b); -- (i))

using namespace std;

int T, n, m, ans[1005];

char g[1005][1005];

int tag[1005];

signed main () {

    cin >> T;

    while (T --) {

        cin >> n >> m;

        rep (i, 1, m) {

            cin >> g[i];

            cin >> ans[i];

            tag[i] = 1;

        }

        int cnt = 0;

        while (cnt < m) {

            rep (i, 0, n - 1) {

                int nw = -1, ed = 1;

                rep (j, 1, m) {

                    if (tag[j] == 1 && g[j][i] == '0') {

                        if (nw == -1) nw = ans[j];

                        if (nw != ans[j]) ed = 0;

                    }

                }

                if (ed) {

                    rep (j, 1, m) if (g[j][i] == '0') tag[j] = 0;

                }

                nw = -1, ed = 1;

                rep (j, 1, m) {

                    if (tag[j] == 1 && g[j][i] == '1') {

                        if (nw == -1) nw = ans[j];

                        if (nw != ans[j]) ed = 0;

                    }

                }

                if (ed) {

                    rep (j, 1, m) if (g[j][i] == '1') tag[j] = 0;

                }

            }

            int nw = 0;

            rep (i, 1, m) nw += (! tag[i]);

            if (cnt == nw) break;

            cnt = nw;

        }

        if (cnt == m) puts ("OK");

        else puts ("LIE");

    }

    return 0;

}

后记

本场比赛难度还是有的,应该是橙橙黄的难度。打完这个以后还有银组,希望我能在印祖取得好成绩QAQ。

USACO 2022 Cu 题解的更多相关文章

  1. 背包九讲 附:USACO中的背包问题

    附:USACO中的背包问题 USACO是USA Computing Olympiad的简称,它组织了很多面向全球的计算机竞赛活动. USACO Trainng是一个很适合初学者的题库,我认为它的特色是 ...

  2. USACO 5.4 章节

    Canada Tour 题目大意 双向连通图,点从左向右排列, 你需要先从最左的点到最右的点,(过程中只能从左向右走) 然后再从最右的点返回最左的点,(过程中只能从右向左走) 过程中除了最左的点,其它 ...

  3. TYVJ P1081 最近距离 Label:这不是分治!!!

    描述    在一块地上,有着n(1<=n<=2000) 头牛,输入n,再分别输入这n头牛的坐标(x,y) (1<=x<=100000,1<=y<=100000),如 ...

  4. poj 2186 Popular Cows

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29908   Accepted: 12131 De ...

  5. TYVJ P1074 武士风度的牛 Label:跳马问题

    背景 农民John有很多牛,他想交易其中一头被Don称为The Knight的牛.这头牛有一个独一无二的超能力,在农场里像Knight一样地跳(就是我们熟悉的象棋中马的走法).虽然这头神奇的牛不能跳到 ...

  6. 【刷题】洛谷 P1519 穿越栅栏 Overfencing

    题目描述 描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫.幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口.更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意 ...

  7. 解题:USACO13FEB Taxi

    题面 因为每次只能载一头牛,所以总路程=每头牛的距离+回头路的最短距离,于是问题变成了如何求回头路的最短距离 我们可以把起点和终点存在两个数组里,然后将两个数组排序后取对应位置相减的绝对值就是每次走回 ...

  8. 【POJ 2387 Til the Cows Come Home】

    Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 59755Accepted: 20336 Description Bessie is ...

  9. POJ1984 Navigation Nightmare —— 种类并查集

    题目链接:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K T ...

  10. usaco training 3.4.3 fence9 题解

    Electric Fence题解 Don Piele In this problem, `lattice points' in the plane are points with integer co ...

随机推荐

  1. SpringCloud学习 系列三、 创建一个没有使用springCloud的服务提供者和消费者

    系列导航 SpringCloud学习 系列一. 前言-为什么要学习微服务 SpringCloud学习 系列二. 简介 SpringCloud学习 系列三. 创建一个没有使用springCloud的服务 ...

  2. node-sass安装失败问题

    在node 中安装sass依赖总会出现各种各样的问题,第一次遇见这样的问题 Cached binary found at C:\Users\ltzhouhuan\AppData\Roaming\npm ...

  3. python之排序的几种方法

    一.通过sort()可以快速实现数组的排序: 1 a=[2,3,1] 2 a.sort() 3 print(a) 打印返回结果: 二.如果不知道有sort()函数或者一些特殊场景需要排序时,如果解决呢 ...

  4. Ubuntu解决Github无法访问的问题

    技术背景 由于IP设置的问题,有时候会出现Github无法访问的问题,经过一番的资料检索之后,发现如下的方案可以成功解决在Ubuntu下无法正常访问Github的问题(有时候可以打开,有时候又不行). ...

  5. 基本操作Linux

    基本操作Linux 关机,重启# 关机 shutdown -h now # 重启 shutdown -r now 查看系统,CPU信息# 查看系统内核信息 uname -a # 查看系统内核版本 ca ...

  6. 【Nginx系列】(一)Nginx基础概念

    有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 文章更新计划 系列文章地址 Nginx的三个主要应用场景 静态 ...

  7. 【面试题精讲】什么是websocket?如何与前端通信?

    > 有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准`https://blog.zysicyj.top` [首发博客地址](https://blog.zysicyj.t ...

  8. [转帖]内存管理参数zone_reclaim_mode分析

    zone_reclaim_mode 官方解释 调整方法 调整的影响 官方解释 最近在性能优化,看到了zone_reclaim_mode参数,记录备用 zone_reclaim_mode: Zone_r ...

  9. [转帖]深入理解mysql-第六章 mysql存储引擎InnoDB的索引-B+树索引

    一.引入索引 在没有索引的情况下,不论是根据主键列或者其他列的值进行查找,由于我们并不能快速的定位到记录所在的页,所以只能从第一个页沿着双向链表一直往下找,因为要遍历所有的数据页,时间复杂度就是O(n ...

  10. [转帖]Kubernetes-18:Dashboard安装及使用

    https://www.cnblogs.com/v-fan/p/13950268.html Helm安装Dashboard 简介 Dashboard 是 kubernetes 的图形化管理工具,可直观 ...