目录
B. Robin Hood and the Major Oak
先说一下这是我的第一篇题解,语言组织可能有点不妥。
A. Robin Helps
题目大意:
英勇的亡命之徒罗宾汉以从富人那里拿走金钱并给予穷人而闻名。罗宾遇到n个人,从第1个人到第n个人。第i个人拥有ai金。如果ai≥k,罗宾将把所有的ai金拿走;如果ai=0,且罗宾有金的话,他将给予1金。罗宾开始时没有金。请找出罗宾将给予多少人金。
输入:
第一行输入包含一个整数t (1≤t≤10^4) — 测试用例的数量。
每个测试用例的第一行包含两个整数n, k (1≤n≤50, 1≤k≤100) — 人数和罗宾汉拿走金的阈值。
每个测试用例的第二行包含n个整数a1, a2, …, an (0≤ai≤100) — 每个人的金。
输出:
对于每个测试用例,输出一个整数,表示将从罗宾汉那里得到金的人数。
解题思路:
循环模拟即可。
代码如下:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
int w, n, k, ans, m;
while (t--)
{
cin >> n >> k;
w = 0;
ans = 0;
for (int i = 0; i < n; i++)
{
cin >> m;
if (m >= k)
{
w += m;
}
if (m == 0 && w != 0)
{
w--;
ans++;
}
}
cout << ans << endl;
}
}
B. Robin Hood and the Major Oak
题目大意:
Sherwood的Major Oak因其壮丽的树叶而闻名,这些树叶为罗宾汉和他的快乐伙伴们提供了庇护。
Major Oak在第i年生长出i片新叶。第1年开始时,它会在第1年有1片叶子。
叶子在树上会持续k年。换句话说,在第i年生长的叶子在第i年到第i+k−1年期间有效。
罗宾认为偶数是幸运的。帮助罗宾确定在第n年Major Oak会有偶数片叶子吗。
输入
输入的第一行包含一个整数t (1≤t≤10^4) — 测试案例的数量。
每个测试案例由两个整数n,k (1≤n≤10^9 ,1≤k≤n) — 请求的年份和叶子保持的年份组成。
输出
对于每个测试案例,输出一行,如果在第n年Major Oak将有偶数片叶子,则输出“YES”,否则输出“NO”。
你可以用任何大小写输出答案(大写或小写)。例如,“yEs”,“yes”,“Yes”,和“YES”都将被视为肯定的回答。
解题思路:
叶子保存k年,就是只需要考虑n-k+1到n年的情况,这是个等差数列求和,公式如下
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int t;
cin >> t;
int w, n, k, ans, m;
while (t--)
{
int n, k;
cin >> n >> k;
int w = n - k + 1;
if (w < 1)
{
w = 1;
}
int sum = (n - w + 1) * (w + n) / 2;
if (sum % 2 == 0)
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
}
C. Robin Hood in Town
题目大意:
环顾四周,富人越来越富,穷人越来越穷。我们需要从富人那里拿走一些财富,给穷人。我们需要罗宾汉!
在这个镇上住着 n 个人。现在,第 i 个人的财富是 a[i] 黄金。但是,你知道吗?最富有的人发现了一锅额外的黄金!
更正式地说,找出 a[j] = max(a[1], a[2], ..., a[n]),将 a[j] 改为 a[j] + x,其中 x 是锅中找到的非负整数黄金。如果有多个最大值,可以是其中任何一个。
如果一个人的财富严格低于平均财富的二分之一,他们就会感到不快乐。
如果超过一半的人口 n 都感到不快乐,罗宾汉将应公众的要求出现。
确定使罗宾汉出现所需的 x 的最小值,如果不可能,则输出 -1。
- 平均财富定义为总财富除以总人口 n,即 ∑ a[i] / n,结果是一个实数。
输入:
第一行输入一个整数 t (1 ≤ t ≤ 10^4) — 测试用例的数量。
每个测试用例的第一行输入一个整数 n (1 ≤ n ≤ 2 · 10^5) — 总人口。
每个测试用例的第二行输入 n 个整数 a[1], a[2], …, a[n] (1 ≤ a[i] ≤ 10^6) — 每个人的财富。
可以保证,所有测试用例中 n 的总和不超过 2 · 10^5。
输出:
对于每个测试用例,输出一个整数 — 最富有的人必须找到的黄金最小数量,以便罗宾汉出现。如果不可能,输出 -1。
解题思路:
将每个人金子从小到大排序,找到刚刚好超过一半人的那个人,即第个人,线下取整。
通过这个数,算出总和至少需要多少,最后x为需要总和-当前综合。
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define int long long
vector<int> a(2 * 100005);
signed main()
{
int t;
cin >> t;
int w, n, k, ans, m;
while (t--)
{
int n;
cin >> n;
int sum = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
}
if (n <= 2)
{
cout << -1 << endl;
continue;
}
sort(a.begin() + 1, a.begin() + n + 1);
w=(n+2)/2;
int x=a[w];
x=x*n*2;
ans=x+1-sum;
if(ans<0){
ans=0;
}
cout << ans << endl;
}
}
D. Robert Hood and Mrs Hood
题目大意:
罗宾的兄弟和母亲正在拜访,而罗宾可以选择每位访客的开始日期。
所有的日子都被编号为1到n。访客会连续停留d天,所有这些d天必须在第1天到第n天之间(包括第1天和第n天)。
罗宾总共计划了k个有风险的“工作”。第i个工作发生在第li天到第ri天之间(包括第li天和第ri天),条件为1≤i≤k。如果一个工作在任何d天内进行,那么这次拜访就会与这个工作重叠(重叠的长度不重要)。
罗宾希望他兄弟的拜访能够与尽可能多的不同工作重叠,而他母亲的拜访则重叠的工作数量要尽量少。
找出罗宾的兄弟和母亲的合适开始日期。如果有多个合适的日期,选择最早的一个。
输入:
第一行输入一个整数t(1≤t≤104)——测试用例的数量。
每个测试用例的第一行包含三个整数n、d、k(1≤n≤105,1≤d,k≤n)——总天数、访客的停留天数和工作的数量。
接下来的k行,每行包含两个整数li和ri(1≤li≤ri≤n)——每个工作的开始和结束天。
保证所有测试用例中n的总和不超过2⋅105。
输出:
对于每个测试用例,输出两个整数,分别表示罗宾的兄弟和母亲的最佳开始日期。两次拜访都必须在第1天和第n天之间(包括第1天和第n天)。
解题思路:
用差分,来记录区间的变化,要注意的是因为有一段工作在,就需要记录,而不是要包含这个工作,所以分别用a,b来记录工作的开始结束。先算出前d天,然后之后每次减去i-d天结束的加上i天开始的。
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n;
signed main()
{
int t;
cin >> t;
int d, k;
while (t--)
{
cin >> n >> d >> k;
int l, r;
vector<int> a(100005, 0);
vector<int> b(100005, 0);
for (int i = 1; i <= k; i++)
{
cin >> l >> r;
a[l]++;
b[r]--;
}
int x, y;
int max1 = 0, min1 = n;
int s = 0;
for (int i = 1; i <= d; i++)
{
if (a[i] == 1)
{
s++;
}
}
x = 1, y = 1;
max1 = s;
min1 = s;
for (int i = d + 1; i <= n; i++)
{
if (b[i - d] < 0)
{
s += b[i - d];
}
s += a[i];
if (max1 < s)
{
max1 = s;
x = i - d + 1;
}
if (min1 > s)
{
min1 = s;
y = i - d + 1;
}
}
cout << x << " " << y << endl;
}
}