比赛链接:https://codeforces.com/contest/2266
A. Good Contest
time limit per test: 1 second / memory limit per test: 256 megabytes
input: standard input / output: standard output
The next programming contest has three problems andnparticipants.
Problem1is easy, problem2is medium, and problem3is hard.
A participant is called weak if they did not solve all three problems.
Unfortunately, the scoreboard was lost. The only remaining information is an arrayaof length3, wherea_iis the number of participants who solved problemi.
Among all scoreboards consistent with this information, find the minimum possible number of weak participants.
Input
The first line contains an integert(1 <= t <= 3000) — the number of test cases.
The first line of each test case contains an integern(1 <= n <= 9) — the number of participants.
The second line of each test case contains three integersa_1, a_2, a_3(0 <= a_i <= n), wherea_iis the number of participants who solved problemi.
Output
For each test case, print a single integer — the minimum possible number of weak participants.
题意大概是有三道题,有n个学生去写,如果一个学生没有全部写对就算weak participants,要求这个weak participants人数的最小值
令p = 三道题中被写出最少的题的次数
容易得到n - p就是答案
因为最多有p个人全对,那么剩下的必然不可能全对,n - p就是最大值
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
vector<int> a(3);
cin >> a[0] >> a[1] >> a[2];
cout << n - min({a[0], a[1], a[2]}) << '\n';
}
}
B. Three Piles
time limit per test: 1 second / memory limit per test: 256 megabytes
input: standard input / output: standard output
Alice and Bob are playing a game with three piles of stones. Initially, Alice hasastones, Bob hasbstones, and the third pile containscstones.
Alice and Bob take turns, with Alice going first. On each turn, the current player may take any number of stones from the third pile, possibly zero, and add them to their own pile.
If both players take zero stones on two consecutive turns, the game ends.
LetAandBbe the final numbers of stones Alice and Bob have, respectively. The score of the game is|A - B|.
Alice wants to maximize the score, while Bob wants to minimize it. Assuming both players play optimally, find the final score.
Input
The first line contains an integert(1 <= t <= 10^4) — the number of test cases.
Each test case contains three integersa,b, andc(0 <= a, b, c <= 10^9) — the initial numbers of stones Alice has, Bob has, and the third pile has, respectively.
Output
For each test case, output one integer — the final score if both players play optimally.
It is important to use a64-bit integer type, such aslong longin C++.
题目翻译一下大概是这样的:
爱丽丝和鲍勃正在玩一个涉及三堆石头的游戏.最初,爱丽丝有a个石头,鲍勃有b个石头,第三堆中有c个石头
爱丽丝和鲍勃轮流行动,由爱丽丝先手.每轮,当前玩家可以从第三堆中取任意数量的石头(包括零个),并将它们加入自己的堆中
如果双方在连续两轮中都未取石头,游戏结束
设A和B分别表示爱丽丝和鲍勃最终拥有的石头数量.游戏得分是|A - B|
爱丽丝希望将得分最大化,而鲍勃希望将得分最小化.假设双方都采取最优策略,求最终得分
第三堆是双方唯一的石头来源,所以自己的石头只会越加越多,设爱丽丝一共取了x个,答案只可能在x的两个端点上产生.
- 全取(
x = c):第三堆空了,Bob只能取0,分数只能为|a + c - b| - 全不取(
x = 0):若a <= b,Bob多取只会拉大差距,所以他会取0个,得到|a - b|;若a > b,Bob会减小差距,但此时a - b < a + c - b,即|a - b|本来就小于另一端,不影响答案
中间取法都会被Bob抵消到不超过这两端,所以答案就是两端取大:
ans = max(|a - b|, |a - b + c|)
代码里第二项写
c + a - b没套abs,因为它为负时必定小于|a - b|
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--)
{
long long a, b, c;
cin >> a >> b >> c;
long long ans = max(llabs(a - b), c + a - b);
cout << ans << '\n';
}
}
C. AND, OR, Sort!
time limit per test: 2 seconds / memory limit per test: 256 megabytes
input: standard input / output: standard output
You are given a binary stringsof lengthn.
You may perform the following operation any number of times (possibly zero):
choose an integeri(1 <= i <= n), and replaces_iwith either the bitwise AND or the bitwise OR ofs_1, s_2, ..., s_i.
Note that the bitwise AND or the bitwise OR of a single element is equal to the element itself.
Your goal is to makessorted in non-decreasing order (that iss_1 <= s_2 <= ... <= s_n).
Find the minimum number of operations required to sortsin non-decreasing order.
Input
The first line contains a single integert(1 <= t <= 10^4) — the number of test cases.
The first line of each test case contains a single integern(2 <= n <= 2*10^5) — the length of the binary strings.
The second line of each test case contains the binary stringsof lengthn. Each character ofsis either0or1.
It is guaranteed that the sum ofnover all test cases does not exceed2*10^5.
Output
For each test case, print a single integer — the minimum number of operations required to sortsin non-decreasing order.
这道题给了两种操作,一种是AND一种是OR
要求把一个二进制字符串变成非递减排序的(也就是递增排序),答案格式会是00000...11111这样的,从中间某个地方开始后面全是1前面全是0
AND能把第i位变成前i位的AND:只要前i位里有0就能把这一位改成0.因为第一位就是0,所以任何1都能变0(变变你的)
对称地,OR能把第i位变成前i位的OR:只有前i位里出现过1,才能把这一位的0变成1
一次操作只改一位,先做
OR再做AND互不干扰,所以代价就等于需要改的位数
当第一个位是1时,前缀的AND和OR恒为1,也就是1永远变不回0,最终必定全是1,操作次数就是0的个数zeros
方便起见我们用zeros表示0的个数
不妨设答案在p处分界,前p个字符全是0,后n - p个字符全是1
那么就有ans = ones(p) + ( zeros - zeros(p) ),前一项是把前p位的1改成0,后一项是把后段的0改成1
不妨令bal = ones(p) - zeros(p),那么ans = zeros + bal,只要枚举p = 0, 1, ..., n取bal的最小值(p = 0时bal = 0,所以代码里m初值取0)
ans = zeros + min(bal(p))
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
string s;
cin >> s;
int zeros = 0;
for (char ch : s)
if (ch == '0')
zeros++;
if (s[0] == '1')
{
cout << zeros << '\n';
}
else
{
int bal = 0, m = 0;
for (char ch : s)
{
bal += (ch == '1') ? 1 : -1;
m = min(m, bal);
}
cout << zeros + m << '\n';
}
}
}
D. Falling Concrete
time limit per test: 2 seconds / memory limit per test: 256 megabytes
input: standard input / output: standard output
Vihaan is repairing a road consisting ofnsections. The height of thei-th section isa_i.
He has a forklift which can move road sections. In one operation, Vihaan chooses two indicesiandj(1 <= i < j <= n), picks up thej-th section, and moves it backwards to positioni.
As the section is carried backwards, one unit of concrete falls from it onto each section it passes over. Then, the carried section is inserted at positioni.
More formally, the subarray[a_i, a_{i+1}, ..., a_{j-1}, a_j]is replaced with[a_j - (j - i), a_i + 1, a_{i+1} + 1, ..., a_{j-1} + 1].
A part of the road is called flat if it is a contiguous segment of sections with equal heights.
Vihaan may perform any number of operations, possibly zero.
Find the maximum possible length of a flat part of the road.
Input
The first line contains an integert(1 <= t <= 10^4) — the number of test cases.
The first line of each test case contains an integern(1 <= n <= 2*10^5) — the number of sections of the road.
The second line containsnintegersa_1, a_2, ..., a_n(n <= a_i <= 10^9) — the initial heights of the sections.
It is guaranteed that the sum ofnover all test cases does not exceed2*10^5.
It can be shown that under the given constraints, the height of every section remains positive after any sequence of operations.
Output
For each test case, print a single integer — the maximum possible length of a flat part of the road.
令v[i] = a_i - i,一次操作恰好等价于把v的区间循环右移
因为操作后第i位是a_j - (j - i),减掉下标正好是v[j];后面每一位都+1而下标也+1,v的值不变,只是整体后挪一格.也就是说,操作只是把v[j]搬到v[i](虽然位置变了,但是差值没变)
当j = i + 1时,就变成了交换相邻两个值,可以得到v是可以重排的
一段等高h(第l位到第r位)意味着v[l] = h - l, v[l+1] = h - l - 1, ...,也就是v里的一串连续整数
所以答案就是v的不同值中最长的连续整数链长度:算出所有v[i],排序去重后扫一遍相邻差恰为1的最长连续段就能得到答案
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
vector<long long> v(n);
for (int i = 0; i < n; i++)
{
long long x;
cin >> x;
v[i] = x - i;
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
int m = 1, cur = 1;
for (int i = 1; i < v.size(); i++)
{
cur = (v[i] == v[i - 1] + 1) ? cur + 1 : 1;
m = max(m, cur);
}
cout << m << '\n';
}
}
附件下载
- Codeforces Round 1122 (Div. 3).md(11 KB · 259 行)