双指针大总结
1.A-B 数对
题目背景
出题是一件痛苦的事情!
相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!
题目描述
给出一串正整数数列以及一个正整数 \(C\),要求计算出所有满足 \(A - B = C\) 的数对的个数(不同位置的数字一样的数对算不同的数对)。
输入格式
输入共两行。
第一行,两个正整数 \(N,C\)。
第二行,\(N\) 个正整数,作为要求处理的那串数。
输出格式
一行,表示该串正整数中包含的满足 \(A - B = C\) 的数对的个数。
样例 #1
样例输入 #1
4 1
1 1 2 3
样例输出 #1
3
提示
对于 \(75\%\) 的数据,\(1 \leq N \leq 2000\)。
对于 \(100\%\) 的数据,\(1 \leq N \leq 2 \times 10^5\),\(0 \leq a_i <2^{30}\),\(1 \leq C < 2^{30}\)。
2017/4/29 新添数据两组
代码:
#include<iostream>
#include<algorithm>
#define int long long
int n, c;
const int N = 2e5 + 10;
int a[N];
using namespace std;
signed main()
{
cin >> n >> c;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + 1 + n);
int i = 1, j = 1,ans=0;
for (int k = 1; k <= n; k++) {
while (i <= n && a[i] - a[k] < c) i++;
while (j <= n && a[j] - a[k] <= c) j++;
ans += j - i ;
}
cout << ans;
return 0;
}
2.逛画展
题目描述
博览馆正在展出由世上最佳的 \(m\) 位画家所画的图画。
游客在购买门票时必须说明两个数字,\(a\) 和 \(b\),代表他要看展览中的第 \(a\) 幅至第 \(b\) 幅画(包含 \(a,b\))之间的所有图画,而门票的价钱就是一张图画一元。
Sept 希望入场后可以看到所有名师的图画。当然,他想最小化购买门票的价格。
请求出他购买门票时应选择的 \(a,b\),数据保证一定有解。
若存在多组解,输出 \(a\) 最小的那组。
输入格式
第一行两个整数 \(n,m\),分别表示博览馆内的图画总数及这些图画是由多少位名师的画所绘画的。
第二行包含 \(n\) 个整数 \(a_i\),代表画第 \(i\) 幅画的名师的编号。
输出格式
一行两个整数 \(a,b\)。
样例 #1
样例输入 #1
12 5
2 5 3 1 3 2 4 1 1 5 4 3
样例输出 #1
2 7
提示
数据规模与约定
- 对于 \(30\%\) 的数据,有 \(n\le200\),\(m\le20\)。
- 对于 \(60\%\) 的数据,有 \(n\le10^5\),\(m\le10^3\)。
- 对于 \(100\%\) 的数据,有 \(1\leq n\le10^6\),\(1 \leq a_i \leq m\le2\times10^3\)。
代码
#include<iostream>
using namespace std;
int n, m;
const int N = 1e6 + 10;
int a[N];
int cnt[2002];
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
int l = 1, r = 1, len = 1e9;
int num = 1; cnt[a[1]]=1;
for (int i = 1,j = 1; j <= n;) {
if (num < m) {
j++;
if (cnt[a[j]] == 0) num++;
cnt[a[j]]++;
}
if (num == m) {
if (len > j - i + 1) {
len = j - i + 1;
l = i, r = j;
}
cnt[a[i]]--;
if (cnt[a[i]] == 0) num--;
i++;
}
}
cout << l << " " << r << endl;
return 0;
}
3.连续自然数和
P1147 连续自然数和 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目描述
对一个给定的正整数 \(M\),求出所有的连续的正整数段(每一段至少有两个数),这些连续的自然数段中的全部数之和为 \(M\)。
例子:\(1998+1999+2000+2001+2002 = 10000\),所以从 \(1998\) 到 \(2002\) 的一个自然数段为 \(M=10000\) 的一个解。
输入格式
包含一个整数的单独一行给出 \(M\) 的值(\(10 \le M \le 2,000,000\))。
输出格式
每行两个正整数,给出一个满足条件的连续正整数段中的第一个数和最后一个数,两数之间用一个空格隔开,所有输出行的第一个按从小到大的升序排列,对于给定的输入数据,保证至少有一个解。
样例 #1
样例输入 #1
10000
样例输出 #1
18 142
297 328
388 412
1998 2002
代码:
//复盘一下,好像9月份确实是啥也没干
#include<iostream>
using namespace std;
int main()
{
int i = 1, j = 1;
int m; cin >> m;
int sum = 1;
while (i <= m / 2) {
if (sum < m) {
j++;
sum += j;
}
else if (sum >= m) {
if (sum == m) {
cout << i << " " << j << endl;
}
sum -= i;
i++;
}
}
return 0;
}
4.[ABC098D] Xor Sum 2
题面翻译
给你一串数 \(a\)
求出满足\(a_l+\cdots +a_r=a_l\operatorname{xor}\cdots\operatorname{xor}a_r,l\le r\) 的 \((i,j)\) 的数量
\(1\le n\le 200000,\forall 1\le i\le n,0\le a_i<2^{20}(1048576)\)
题目描述
長さ $ N $ の整数列 $ A $ があります。
次の条件を満たす整数 $ l $, $ r $ ( $ 1\ \leq\ l\ \leq\ r\ \leq\ N $ ) の組の個数を求めてください。
- $ A_l\ xor\ A_{l+1}\ xor\ ...\ xor\ A_r\ =\ A_l\ +\ A_{l+1}\ +\ ...\ +\ A_r $
xorの説明
整数 $ c_1,\ c_2,\ ...,\ c_m $ の $ xor $ は以下のように定義されます。
- $ xor $ の値を $ X $ とおく。$ X $ を $ 2 $ 進数表記したときの $ 2^k $ ( $ 0\ \leq\ k $, $ k $ は整数 ) の位の値は、$ c_1,\ c_2,\ ...c_m $ のうち、$ 2 $ 進数表記したときの $ 2^k $ の位の値が $ 1 $ となるものが奇数個ならば $ 1 $、偶数個ならば $ 0 $ となる。
例えば、$ 3 $ と $ 5 $ の $ xor $ の値は、$ 3 $ の $ 2 $ 進数表記が $ 011 \(、\) 5 $ の $ 2 $ 進数表記が $ 101 $ のため、$ 2 $ 進数表記が $ 110 $ の $ 6 $ となります。
输入格式
入力は以下の形式で標準入力から与えられる。
$ N $ $ A_1 $ $ A_2 $ $ ... $ $ A_N $
输出格式
条件を満たす整数 $ l $, $ r $ ( $ 1\ \leq\ l\ \leq\ r\ \leq\ N $ ) の組の個数を出力せよ。
样例 #1
样例输入 #1
4
2 5 4 6
样例输出 #1
5
样例 #2
样例输入 #2
9
0 0 0 0 0 0 0 0 0
样例输出 #2
45
样例 #3
样例输入 #3
19
885 8 1 128 83 32 256 206 639 16 4 128 689 32 8 64 885 969 1
样例输出 #3
37
提示
制約
- $ 1\ \leq\ N\ \leq\ 2\ \times\ 10^5 $
- $ 0\ \leq\ A_i $
- 入力はすべて整数である
Sample Explanation 1
明らかに、$ (l,r)=(1,1),(2,2),(3,3),(4,4) $ は条件を満たします。 また、$ (l,r)=(1,2) $ の場合、$ A_1\ xor\ A_2\ =\ A_1\ +\ A_2\ =\ 7 $ となるので、これも条件を満たします。 ほかに条件を満たす組はないので、答えは $ 5 $ になります。
代码:
#include<iostream>
using namespace std;
int a[200005];
int j, ans,s1,s2;
int main()
{
int n; cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1;i <= n;) {
while (j + 1 <= n && (s1 + a[j + 1]) == (s2 ^ a[j + 1])) {
s1 += a[j + 1];
s2 ^= a[j + 1];
j++;
}
ans += j - i + 1;
s1 -= a[i];
s2^= a[i];
i++;
}
cout << ans;
return 0;
}
5.单词背诵
题目描述
灵梦有 \(n\) 个单词想要背,但她想通过一篇文章中的一段来记住这些单词。
文章由 \(m\) 个单词构成,她想在文章中找出连续的一段,其中包含最多的她想要背的单词(重复的只算一个)。并且在背诵的单词量尽量多的情况下,还要使选出的文章段落尽量短,这样她就可以用尽量短的时间学习尽可能多的单词了。
输入格式
第 \(1\) 行一个数 \(n\),接下来 \(n\) 行每行是一个长度不超过 \(10\) 的字符串,表示一个要背的单词。
接着是一个数 \(m\),然后是 \(m\) 行长度不超过 \(10\) 的字符串,每个表示文章中的一个单词。
输出格式
输出文件共 \(2\) 行。第 \(1\) 行为文章中最多包含的要背的单词数,第 \(2\) 行表示在文章中包含最多要背单词的最短的连续段的长度。
样例 #1
样例输入 #1
3
hot
dog
milk
5
hot
dog
dog
milk
hot
样例输出 #1
3
3
提示
数据规模与约定
- 对于 \(30\%\) 的数据,\(n \le 50\),\(m \le 500\);
- 对于 \(60\%\) 的数据,\(n \le 300\),\(m \le 5000\);
- 对于 \(100\%\) 的数据,\(n \le 1000\),\(m \le 10^5\)。
代码:
#include<iostream>
#include<map>
using namespace std;
string s[100005], s1;
int n, m;
map<string, bool> word;
map<string, int> cnt;
int sum, len;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s1; word[s1] = 1;
}
//输入s数组
cin >> m;
for (int i = 1; i <= m; i++) cin >> s[i];
//使用双指针进行遍历
for (int i = 1, j = 1; j <= m; j++) {
if (word[s[j]]) cnt[s[j]]++;
if (cnt[s[j]] == 1) sum++, len = j - i + 1;
while (i <= j) {
if (cnt[s[i]] == 1) break;
if (cnt[s[i]] > 1) cnt[s[i]]--, i++;
if (!word[s[i]]) i++;
}
len = min(len, j - i + 1);
}
cout << sum << endl << len << endl;
return 0;
}
6.Maximum Sum
Submission #285160382 - Codeforces
题面翻译
本题有多组测试数据
给定一个长度为 \(n\) 的数列,其中每个元素互不相同,进行 \(k\) 次操作,每次可以选择删除序列中最小的两个数或最大的一个数。求操作后剩余数的和的最大值。
\(3 \leq n \leq 2 \times 10^{5},1 \leq k \leq 99999,2k \leq n\)。
题目描述
You are given an array $ a_1, a_2, \dots, a_n $ , where all elements are different.
You have to perform exactly $ k $ operations with it. During each operation, you do exactly one of the following two actions (you choose which to do yourself):
- find two minimum elements in the array, and delete them;
- find the maximum element in the array, and delete it.
You have to calculate the maximum possible sum of elements in the resulting array.
输入格式
The first line contains one integer $ t $ ( $ 1 \le t \le 10^4 $ ) — the number of test cases.
Each test case consists of two lines:
- the first line contains two integers $ n $ and $ k $ ( $ 3 \le n \le 2 \cdot 10^5 $ ; $ 1 \le k \le 99999 $ ; $ 2k < n $ ) — the number of elements and operations, respectively.
- the second line contains $ n $ integers $ a_1, a_2, \dots, a_n $ ( $ 1 \le a_i \le 10^9 $ ; all $ a_i $ are different) — the elements of the array.
Additional constraint on the input: the sum of $ n $ does not exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, print one integer — the maximum possible sum of elements in the resulting array.
样例 #1
样例输入 #1
6
5 1
2 5 1 10 6
5 2
2 5 1 10 6
3 1
1 2 3
6 1
15 22 12 10 13 11
6 2
15 22 12 10 13 11
5 1
999999996 999999999 999999997 999999998 999999995
样例输出 #1
21
11
3
62
46
3999999986
提示
In the first testcase, applying the first operation produces the following outcome:
- two minimums are $ 1 $ and $ 2 $ ; removing them leaves the array as $ [5, 10, 6] $ , with sum $ 21 $ ;
- a maximum is $ 10 $ ; removing it leaves the array as $ [2, 5, 1, 6] $ , with sum $ 14 $ .
$ 21 $ is the best answer.
In the second testcase, it's optimal to first erase two minimums, then a maximum.
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
int t;
const int N = 2e5 + 10;
int a[N],s[N];
void solve() {
int n,k; cin >> n>>k;
memset(a, 0, sizeof(a));
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + 1 + n);
//一定要记得排序之后在进行前缀和操作
memset(s, 0, sizeof(s));
for (int i = 1; i <= n; i++) {
s[i] = s[i - 1] + a[i];
}
//假设我对删除两个最小的值这个操作进行了i次,那么就对删除最大值就进行了(k-i)次,那么我只需要把那些删掉的东西拿走就好了,然后遍历i,从0<=i<=k
int ans = 0;
for (int i = 0; i <= k; i++) {
ans = max(ans, s[n - (k - i)] - s[2 * i]);
}
cout << ans << endl;
}
signed main()
{
cin >> t;
while (t--) {
solve();
}
return 0;
}
7.Right Left Wrong
题面翻译
题目描述
Vlad发现了一个由 \(n\) 细胞组成的条带,从左到右从 \(1\) 到 \(n\) 编号。在 \(i\) 中,有一个正整数 \(a_i\) 和一个字母 \(s_i\) ,其中所有 \(s_i\) 都是'L'或'R'。
Vlad邀请您尝试通过执行任意(可能为零)操作来获得最大可能的分数。
在一次操作中,您可以选择两个索引 \(l\) 和 \(r\) ( \(1 \le l < r \le n\) ),使 \(s_l\) = L
和 \(s_r\) = R
,并执行以下操作:
-
在当前分数基础上增加 \(a_l + a_{l + 1} + \dots + a_{r - 1} + a_r\) 分;
-
将 \(s_i\) 替换为
.
-
对于所有 \(l \le i \le r\) ,这意味着您不能再选择这些索引。
例如,考虑下面的strip:
\(3\) | \(5\) | \(1\) | \(4\) | \(3\) | \(2\) |
---|---|---|---|---|---|
l | r | l | l | l | r |
您可以先选择 \(l = 1\) , \(r = 2\) ,并将 \(3 + 5 = 8\) 添加到您的分数中。
\(3\) | \(5\) | \(1\) | \(4\) | \(3\) | \(2\) |
---|---|---|---|---|---|
。 | 。 | l | l | l | r |
然后选择 \(l = 3\) , \(r = 6\) 并将 \(1 + 4 + 3 + 2 = 10\) 添加到您的分数中。
\(3\) | \(5\) | \(1\) | \(4\) | \(3\) | \(2\) |
---|---|---|---|---|---|
。 | 。 | 。 | 。 | 。 | 。 |
因此无法再进行其他操作,最终得分为 \(18\) 。
能达到的最高分数是多少?
输入格式
输入* * * *
第一行包含一个整数 \(t\) ( \(1 \le t \le 10^4\) )—测试用例的数量。
每个测试用例的第一行包含一个整数 \(n\) ( \(2 \le n \le 2 \cdot 10^5\) )—条带的长度。
每个测试用例的第二行包含 \(n\) 个整数 \(a_1, a_2, \dots, a_n\) ( \(1 \le a_i \le 10^5\) )——写在试纸上的数字。
每个测试用例的第三行包含一个由 \(n\) 字符 L
和 R
组成的字符串 \(s\) 。
可以保证所有测试用例中 \(n\) 的值之和不超过 \(2 \cdot 10^5\) 。
输出格式
对于每个测试用例,输出一个整数—可以得分的最大可能点数。
题目描述
Vlad found a strip of $ n $ cells, numbered from left to right from $ 1 $ to $ n $ . In the $ i $ -th cell, there is a positive integer $ a_i $ and a letter $ s_i $ , where all $ s_i $ are either 'L' or 'R'.
Vlad invites you to try to score the maximum possible points by performing any (possibly zero) number of operations.
In one operation, you can choose two indices $ l $ and $ r $ ( $ 1 \le l < r \le n $ ) such that $ s_l $ = 'L' and $ s_r $ = 'R' and do the following:
- add $ a_l + a_{l + 1} + \dots + a_{r - 1} + a_r $ points to the current score;
- replace $ s_i $ with '.' for all $ l \le i \le r $ , meaning you can no longer choose these indices.
For example, consider the following strip:
$ 3 $ $ 5 $ $ 1 $ $ 4 $ $ 3 $ $ 2 $ LRLLLRYou can first choose $ l = 1 $ , $ r = 2 $ and add $ 3 + 5 = 8 $ to your score.
$ 3 $ $ 5 $ $ 1 $ $ 4 $ $ 3 $ $ 2 $ ..LLLRThen choose $ l = 3 $ , $ r = 6 $ and add $ 1 + 4 + 3 + 2 = 10 $ to your score.
$ 3 $ $ 5 $ $ 1 $ $ 4 $ $ 3 $ $ 2 $ ......As a result, it is impossible to perform another operation, and the final score is $ 18 $ .
What is the maximum score that can be achieved?
输入格式
The first line contains one integer $ t $ ( $ 1 \le t \le 10^4 $ ) — the number of test cases.
The first line of each test case contains one integer $ n $ ( $ 2 \le n \le 2 \cdot 10^5 $ ) — the length of the strip.
The second line of each test case contains $ n $ integers $ a_1, a_2, \dots, a_n $ ( $ 1 \le a_i \le 10^5 $ ) — the numbers written on the strip.
The third line of each test case contains a string $ s $ of $ n $ characters 'L' and 'R'.
It is guaranteed that the sum of the values of $ n $ across all test cases does not exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, output one integer — the maximum possible number of points that can be scored.
样例 #1
样例输入 #1
4
6
3 5 1 4 3 2
LRLLLR
2
2 8
LR
2
3 9
RL
5
1 2 3 4 5
LRLRR
样例输出 #1
18
10
0
22
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 2e5 + 10;
int a[N],s[N];
char c[N];
void solve()
{
int n; cin >> n;
memset(a, 0, sizeof(a)); memset(c, 0, sizeof(c));
for (int i = 1; i <= n; i++) {
cin >> a[i];
s[i] = s[i - 1] + a[i];
}
for (int i = 1; i <= n; i++) cin >> c[i];
int i = 1, j = n,ans=0;
while (1) {
if (i > j) break;
while (i <= j && c[i] != 'L') i++;
while (i<=j && c[j] != 'R') j--;
ans += s[j] - s[i - 1];
i++; j--;
}
cout << ans << endl;
}
signed main()
{
int t; cin >> t;
while (t--) {
solve();
}
return 0;
}
8.Bouquet (Easy Version)
Bouquet (Easy Version) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题面翻译
本题有 \(t\)(\(1\leq t\leq 10000\))组数据。
给定 \(n\)(\(1\leq n\leq 2\times 10^5\))个物品与你所拥有的钱数 \(m\)(\(1\leq m\leq 10^{18}\))。对第 \(i\)(\(i\in [1,n]\))个物品,它的价值和价格均为 \(a_i\)(\(1\leq a_i\leq 10^9\))。
构造一种购买方案,使得你购买的物品的价值的极差不能超过 \(1\) 且总价格不能超过 \(m\)。求你能购买的最大价值。
Translated by @TachibanaKanade
题目描述
This is the easy version of the problem. The only difference is that in this version, the flowers are specified by enumeration.
A girl is preparing for her birthday and wants to buy the most beautiful bouquet. There are a total of $ n $ flowers in the store, each of which is characterized by the number of petals, and a flower with $ k $ petals costs $ k $ coins. The girl has decided that the difference in the number of petals between any two flowers she will use in her bouquet should not exceed one. At the same time, the girl wants to assemble a bouquet with the maximum possible number of petals. Unfortunately, she only has $ m $ coins, and she cannot spend more. What is the maximum total number of petals she can assemble in the bouquet?
输入格式
Each test consists of several test cases. The first line contains a single integer $ t $ ( $ 1 \le t \le 10,000 $ ) — the number of test cases. This is followed by descriptions of the test cases.
The first line of each test case contains two integers $ n $ , $ m $ ( $ 1 \le n \le 2 \cdot 10^5, 1 \le m \le 10^{18} $ ) — the number of flowers in the store and the number of coins the girl possesses, respectively. The second line of each test case contains $ n $ integers $ a_1, a_2, \ldots, a_n $ ( $ 1 \le a_i \le 10^9 $ ), where $ a_i $ is the number of petals of the $ i $ -th flower in the store.
The sum of $ n $ over all test cases does not exceed $ 2 \cdot {10}^5 $ .
输出格式
For each test case, output a single integer — the maximum possible number of petals in the bouquet that the girl can assemble while meeting all the conditions listed above.
样例 #1
样例输入 #1
5
5 10
1 1 2 2 3
8 20
4 2 7 5 6 1 1 1
8 100000
239 30 610 122 24 40 8 2
11 13
2 4 11 1 1 2 3 5 4 3 2
8 1033
206 206 206 207 207 207 207 1000
样例输出 #1
7
13
610
13
1033
提示
In the first test case, you can assemble a bouquet with $ (1, 1, 2, 2), (2, 2, 3), (1, 1), (2, 2) $ . The maximum over all valid bouquets not greater than $ 10 $ is $ 7 $ for $ (2, 2, 3) $ . In the third test case, you can assemble a bouquet with only one flower of any type, so the answer is $ 610 $ . In the fourth test case, you can assemble a bouquet with $ (4, 4, 5) $ , which gives you $ 13 $ petals, and it is the maximum amount of petals that the girl can buy.
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int a[N];
void solve()
{
int n, m;
cin >> n >> m;
memset(a, 0, sizeof(a));
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + 1 + n);
int i = 0, j = 1, ans = 0,x=0;
for (int i = 1; i <= n; i++) {
x += a[i];
while (x > m || a[i] - a[j] > 1) {
x -= a[j];
j++;
}
ans = max(ans, x);
}
cout << ans << endl;
}
signed main()
{
int t; cin >> t;
while (t--) {
solve();
}
return 0;
}
9.Dora and Search
Dora and Search - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题面翻译
题目描述
给定一个长度为 \(n\) 的排列 \(a\) ,问是否存在正整数 \(l,r\) 使得 \(a_l,a_r\) 均不为 \(a_{l...r}\) 中的最大值或最小值。
输入输出格式
第一行一个正整数 \(t\) ,表示数据组数。接下来对于每组数据输入包括两行,第一行一个正整数 \(n\) ,第二行 \(n\) 个正整数代表排列 \(a\) 。
对于每组数据,若存在符合要求的 \(l,r\) ,输出任意一组。若不存在则输出 \(-1\) 。
数据范围
$1\leqslant t \leqslant 10\ 000\ ,\ 1\leqslant \Sigma n \leqslant 200\ 000\ ,\ $ \(a\) 是一个排列。
题目描述
As you know, the girl Dora is always looking for something. This time she was given a permutation, and she wants to find such a subsegment of it that none of the elements at its ends is either the minimum or the maximum of the entire subsegment. More formally, you are asked to find the numbers $ l $ and $ r $ $ (1 \leq l \leq r \leq n) $ such that $ a_l \neq \min(a_l, a_{l + 1}, \ldots, a_r) $ , $ a_l \neq \max(a_l, a_{l + 1}, \ldots, a_r) $ and $ a_r \neq \min(a_l, a_{l + 1}, \ldots, a_r) $ , $ a_r \neq \max(a_l, a_{l + 1}, \ldots, a_r) $ .
A permutation of length $ n $ is an array consisting of $ n $ distinct integers from $ 1 $ to $ n $ in any order. For example, $ [2,3,1,5,4] $ is a permutation, but $ [1,2,2] $ is not a permutation ( $ 2 $ occurs twice in the array) and $ [1,3,4] $ is also not a permutation ( $ n=3 $ , but $ 4 $ is present in the array).
Help Dora find such a subsegment, or tell her that such a subsegment does not exist.
输入格式
Each test consists of multiple test cases. The first line contains a single integer $ t $ ( $ 1 \leq t \leq 10^4 $ ) — the number of test cases. Description of the test cases follows.
For each test case, the first line contains one integer $ n $ ( $ 1 \leq n \leq 2 \cdot 10^5 $ ) — the length of permutation.
The second line contains $ n $ distinct integers $ a_1, a_2, \ldots, a_n $ ( $ 1 \leq a_i \leq n $ ) — the elements of permutation.
It is guarented that the sum of $ n $ over all test cases doesn't exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, output $ -1 $ if the desired subsegment does not exist.
Otherwise, output two indexes $ l, r $ such that $ [a_{l}, a_{l + 1}, \ldots, a_{r}] $ satisfies all conditions.
If there are several solutions, then output any of them.
样例 #1
样例输入 #1
4
3
1 2 3
4
2 1 4 3
7
1 3 2 4 6 5 7
6
2 3 6 5 4 1
样例输出 #1
-1
1 4
2 6
-1
提示
In the first and fourth test cases, it can be shown that there are no desired subsegments.
In the second test case, the subsegment $ [1, 4] $ satisfies all the conditions, because $ \max(a_1, a_2, a_3, a_4) = 4, \min(a_1, a_2, a_3, a_4) = 1 $ , as we see, all the conditions are met.
In the third test case, the subsegment $ [2, 6] $ also satisfies all the conditions described.
代码:
#include<iostream>
#include<cstring>
using namespace std;
const int N = 2e5 + 10;
int a[N];
void solve() {
int n; cin >> n;
memset(a, 0, sizeof(a));
for (int i = 1; i <= n; i++) cin >> a[i];
int l = 1, r = n, mn = 1, mx = n;
while (1) {
if (a[l] == mn) ++mn, ++l;
else if (a[l] == mx) --mx, ++l;
else if (a[r] == mn) ++mn, --r;
else if (a[r] == mx) --mx, --r;
else break;
}
if (l > r) cout << -1 << endl;
else cout << l << " " << r << endl;
}
int main()
{
int t; cin >> t;
while (t--) solve();
return 0;
}
10.Yarik and Array
Yarik and Array - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题面翻译
题目描述
给定一个数组,求数组中连续子数组之和的最大值,但要求子数组必须满足:相邻两项奇偶性不同。
输出最大总和。
输入描述
输入一个整数,第一行一个整数 \(t\) 代表测试样例的组数,
接下来 \(2 \times t\) 行中,第一行输入一个整数 \(n\),第二行输入 \(n\) 个整数表示数组。
输出描述
输出 \(t\) 行,每行一个整数表示答案。
translated by @Liyiyang1123
题目描述
A subarray is a continuous part of array.
Yarik recently found an array $ a $ of $ n $ elements and became very interested in finding the maximum sum of a non empty subarray. However, Yarik doesn't like consecutive integers with the same parity, so the subarray he chooses must have alternating parities for adjacent elements.
For example, $ [1, 2, 3] $ is acceptable, but $ [1, 2, 4] $ is not, as $ 2 $ and $ 4 $ are both even and adjacent.
You need to help Yarik by finding the maximum sum of such a subarray.
输入格式
The first line contains an integer $ t $ $ (1 \le t \le 10^4) $ — number of test cases. Each test case is described as follows.
The first line of each test case contains an integer $ n $ $ (1 \le n \le 2 \cdot 10^5) $ — length of the array.
The second line of each test case contains $ n $ integers $ a_1, a_2, \dots, a_n $ $ (-10^3 \le a_i \le 10^3) $ — elements of the array.
It is guaranteed that the sum of $ n $ for all test cases does not exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, output a single integer — the answer to the problem.
样例 #1
样例输入 #1
7
5
1 2 3 4 5
4
9 9 8 8
6
-1 4 -1 0 5 -4
4
-1 2 4 -3
1
-1000
3
101 -99 101
20
-10 5 -8 10 6 -10 7 9 -2 -6 7 2 -4 6 -1 7 -6 -7 4 1
样例输出 #1
15
17
8
4
-1000
101
10
代码:
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int N = 2e5 + 10;
int a[N];
int dp[N];
void solve()
{
int n; cin >> n;
memset(a, 0, sizeof(a));
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++) cin >> a[i];
dp[0] = 0; dp[1] = a[1];
int ans = dp[1];
for (int i = 2; i <= n; i++) {
if (abs(a[i]) % 2 == abs(a[i - 1]) % 2) dp[i] = a[i];
else dp[i] = max(a[i], dp[i - 1] + a[i]);
ans = max(ans, dp[i]);
}
cout << ans << endl;
}
int main()
{
int t; cin >> t;
while (t--) solve();
return 0;
}
11.Collecting Game
Collecting Game - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题面翻译
长为 \(n\) 的序列,可以进行下面的操作:
- 如果你的分数 \(s\ge a_i,1\le i\le n\),你就可以删去 \(a_i\) 并且将 \(s\) 增加 \(a_i\)。
问:对于每一个 \(i\),删除 \(a_i\) 并将你的分数设为 \(a_i\),你还可以删除多少个数(注意开始删除的数不算)。
\(T\) 组数据,多测。
\(1\le a_i\le10^9,1\le T\le5000,\sum n\le10^5\)。
by @huangrenheluogu
题目描述
You are given an array $ a $ of $ n $ positive integers and a score. If your score is greater than or equal to $ a_i $ , then you can increase your score by $ a_i $ and remove $ a_i $ from the array.
For each index $ i $ , output the maximum number of additional array elements that you can remove if you remove $ a_i $ and then set your score to $ a_i $ . Note that the removal of $ a_i $ should not be counted in the answer.
输入格式
Each test contains multiple test cases. The first line contains an integer $ t $ ( $ 1 \leq t \leq 5000 $ ) — the number of test cases. The description of the test cases follows.
The first line of each test case contains a single integer $ n $ ( $ 1 \le n \le 10^5 $ ) — the length of the array.
The second line of each test case contains $ n $ integers $ a_1, a_2, \ldots, a_n $ ( $ 1 \le a_i \le 10^9 $ ) — the elements of the array.
It is guaranteed that the sum of $ n $ over all test cases does not exceed $ 10^5 $ .
输出格式
For each test case, output $ n $ integers, the $ i $ -th of which denotes the maximum number of additional array elements that you can remove if you remove $ a_i $ from the array and then set your score to $ a_i $ .
样例 #1
样例输入 #1
4
5
20 5 1 4 2
3
1434 7 1442
1
1
5
999999999 999999999 999999999 1000000000 1000000000
样例输出 #1
4 3 0 3 1
1 0 2
0
4 4 4 4 4
提示
In the first test case, the answers are as follows:
If we start with $ i=4 $ , our initial score is $ a_4=4 $ and $ a=[20,5,1,2] $ . We can remove $ 3 $ additional elements in the following order:
- Since $ 4 \ge 1 $ , we can remove $ 1 $ and our score becomes $ 5 $ . After this, $ a=[20,5,2] $ .
- Since $ 5 \ge 5 $ , we can remove $ 5 $ and our score becomes $ 10 $ . After this, $ a=[20,2] $ .
- Since $ 10 \ge 2 $ , we can remove $ 2 $ and our score becomes $ 12 $ . After this, $ a=[20] $ .
If we start with $ i=1 $ we can remove all remaining elements in the array, so the answer is $ 4 $ .
If we start with $ i=2 $ , we can remove $ 3 $ additional elements in the following order: $ 1 $ , $ 4 $ , $ 2 $ .
If we start with $ i=3 $ , we can remove no additional elements.
If we start with $ i=5 $ , we can remove $ 1 $ additional element: $ 1 $ .
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 1e5 + 10;
int ans[N], s[N];
struct node {
int val;
int id;
}a[N];
bool compare(node x, node y)
{
return x.val < y.val;
}
void solve() {
int n; cin >> n;
memset(a, 0, sizeof(a)); memset(s, 0, sizeof(s));
memset(ans, 0, sizeof(ans));
for (int i = 1; i <= n; i++) {
cin >> a[i].val;
a[i].id = i;
}
sort(a + 1, a + 1 + n, compare);
//计算前缀和
for (int i = 1; i <= n; i++) s[i] = s[i - 1] + a[i].val;
int now = 1;
int tot;
for (int i = 1; i <= n; i++) {
now = max(now, i);
tot = s[now];
while (now < n && a[now + 1].val <= tot) {
tot += a[now + 1].val;
now++;
}
ans[a[i].id] = now - 1;
}
for (int i = 1; i <= n; i++) {
cout << ans[i] << " ";
}
cout << endl;
}
signed main()
{
int t; cin >> t;
while (t--) solve();
return 0;
}
12.Very Different Array
Very Different Array - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题面翻译
给你一个长度为 \(n\) 的序列 \(a\),和一个长度为 \(m\) 的序列 \(b\),其中 \(m≥n\)。
你的任务是在 \(b\) 中选出 \(n\) 个数以任意顺序组成序列 \(c\),使得 \(D=\sum _{i=1}^n \left\vert a_i-c_i \right\vert\) 最大。输出 \(D\) 即可。
多组测试数据,\(t≤100\)。
\(1≤n≤m≤2×10^5\)。
\(1≤a_i,b_i≤10^9\)。
题目描述
Petya has an array $ a_i $ of $ n $ integers. His brother Vasya became envious and decided to make his own array of $ n $ integers.
To do this, he found $ m $ integers $ b_i $ ( $ m\ge n $ ), and now he wants to choose some $ n $ integers of them and arrange them in a certain order to obtain an array $ c_i $ of length $ n $ .
To avoid being similar to his brother, Vasya wants to make his array as different as possible from Petya's array. Specifically, he wants the total difference $ D = \sum_{i=1}^{n} |a_i - c_i| $ to be as large as possible.
Help Vasya find the maximum difference $ D $ he can obtain.
输入格式
Each test consists of multiple test cases. The first line contains a single integer $ t $ ( $ 1 \le t \le 100 $ ) — the number of test cases. This is followed by a description of the test cases.
The first line of each test case contains two integers $ n $ and $ m $ ( $ 1\le n\le m\le 2 \cdot 10^5 $ ).
The second line of each test case contains $ n $ integers $ a_i $ ( $ 1\le a_i\le 10^9 $ ). The third line of each test case contains $ m $ integers $ b_i $ ( $ 1\le b_i\le 10^9 $ ).
It is guaranteed that in a test, the sum of $ m $ over all test cases does not exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, output a single integer — the maximum total difference $ D $ that can be obtained.
样例 #1
样例输入 #1
9
4 6
6 1 2 4
3 5 1 7 2 3
3 4
1 1 1
1 1 1 1
5 5
1 2 3 4 5
1 2 3 4 5
2 6
5 8
8 7 5 8 2 10
2 2
4 1
9 6
4 6
8 10 6 4
3 10 6 1 8 9
3 5
6 5 2
1 7 9 7 2
5 5
9 10 6 3 7
5 9 2 3 9
1 6
3
2 7 10 1 1 5
样例输出 #1
16
0
12
11
10
23
15
25
7
提示
In the first example, Vasya can, for example, create the array $ (1, 5, 7, 2) $ . Then the total difference will be $ D = |6-1|+|1-5|+|2-7|+|4-2| = 5+4+5+2 = 16 $ .
In the second example, all the integers available to Vasya are equal to 1, so he can only create the array $ (1, 1, 1) $ , for which the difference $ D = 0 $ .
In the third example, Vasya can, for example, create the array $ (5, 4, 3, 2, 1) $ . Then the total difference will be $ D = |1-5|+|2-4|+|3-3|+|4-2|+|5-1| = 4+2+0+2+4 = 12 $ .
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define int long long
const int N = 2e5 + 10;
int a[N], b[N];
void solve() {
int n, m;
cin >> n >> m;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= m; i++) cin >> b[i];
sort(a + 1, a + 1 + n);
sort(b + 1, b + 1 + m);
int ans = 0;
for (int i = 1; i <= n; i++) {
ans += max(abs(a[i] - b[n - i + 1]), abs(a[i] - b[m - i + 1]));
}
cout << ans << endl;
}
signed main()
{
int t; cin >> t;
while (t--) {
solve();
}
return 0;
}
13.Friends and the Restaurant
Friends and the Restaurant - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题面翻译
给出长度为 \(n\) 的数组 \(x\) 和 \(y\),你可以从中选出一些数,且将这些数分为若干组,求最大组数满足每组的数量至少为 \(2\) 且每组中 \(x\) 的总和不大于 \(y\) 的总和。
By BotDand
题目描述
A group of $ n $ friends decide to go to a restaurant. Each of the friends plans to order meals for $ x_i $ burles and has a total of $ y_i $ burles ( $ 1 \le i \le n $ ).
The friends decide to split their visit to the restaurant into several days. Each day, some group of at least two friends goes to the restaurant. Each of the friends visits the restaurant no more than once (that is, these groups do not intersect). These groups must satisfy the condition that the total budget of each group must be not less than the amount of burles that the friends in the group are going to spend at the restaurant. In other words, the sum of all $ x_i $ values in the group must not exceed the sum of $ y_i $ values in the group.
What is the maximum number of days friends can visit the restaurant?
For example, let there be $ n = 6 $ friends for whom $ x $ = [ $ 8, 3, 9, 2, 4, 5 $ ] and $ y $ = [ $ 5, 3, 1, 4, 5, 10 $ ]. Then:
- first and sixth friends can go to the restaurant on the first day. They will spend $ 8+5=13 $ burles at the restaurant, and their total budget is $ 5+10=15 $ burles. Since $ 15 \ge 13 $ , they can actually form a group.
- friends with indices $ 2, 4, 5 $ can form a second group. They will spend $ 3+2+4=9 $ burles at the restaurant, and their total budget will be $ 3+4+5=12 $ burles ( $ 12 \ge 9 $ ).
It can be shown that they will not be able to form more groups so that each group has at least two friends and each group can pay the bill.
So, the maximum number of groups the friends can split into is $ 2 $ . Friends will visit the restaurant for a maximum of two days. Note that the $ 3 $ -rd friend will not visit the restaurant at all.
Output the maximum number of days the friends can visit the restaurant for given $ n $ , $ x $ and $ y $ .
输入格式
The first line of the input contains an integer $ t $ ( $ 1 \le t \le 10^4 $ ) — the number of test cases in the test.
The descriptions of the test cases follow.
The first line of each test case contains a single integer $ n $ ( $ 2 \le n \le 10^5 $ ) — the number of friends.
The second line of each test case contains exactly $ n $ integers $ x_1, x_2, \dots, x_n $ ( $ 1 \le x_i \le 10^9 $ ). The value of $ x_i $ corresponds to the number of burles that the friend numbered $ i $ plans to spend at the restaurant.
The third line of each test case contains exactly $ n $ integers $ y_1, y_2, \dots, y_n $ ( $ 1 \le y_i \le 10^9 $ ). The value $ y_i $ corresponds to the number of burles that the friend numbered $ i $ has.
It is guaranteed that the sum of $ n $ values over all test cases does not exceed $ 10^5 $ .
输出格式
For each test case, print the maximum number of days to visit the restaurant. If friends cannot form even one group to visit the restaurant, print 0.
样例 #1
样例输入 #1
6
6
8 3 9 2 4 5
5 3 1 4 5 10
4
1 2 3 4
1 1 2 2
3
2 3 7
1 3 10
6
2 3 6 9 5 7
3 2 7 10 6 10
6
5 4 2 1 8 100
1 1 1 1 1 200
6
1 4 1 2 4 2
1 3 3 2 3 4
样例输出 #1
2
0
1
3
1
3
提示
The first test case in explained in the problem statement.
In the second test case, friends cannot form at least one group of two or more people.
In the third test case, one way to visit the restaurant in one day is to go in a group of all three friends ( $ 1+3+10 \ge 2+3+7 $ ). Note that they do not have the option of splitting into two groups.
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define int long long
const int N = 2e5 + 10;
int a[N], b[N],c[N];
void solve() {
int n; cin >> n;
memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); memset(c, 0, sizeof(c));
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i],c[i]=b[i]-a[i];
sort(c + 1, c + 1 + n);
int p = 1, q = n, ans = 0;
while (p < q) {
while (c[p] + c[q] < 0&&p<q) p++;
if (p == q) break;
if (c[p] + c[q] >= 0) ans++;
p++; q--;
}
cout << ans << endl;
}
signed main()
{
int t; cin >> t;
while (t--) {
solve();
}
return 0;
}
14.Binary Deque
题面翻译
Binary Deque - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
有多组数据。
每组数据给出 \(n\) 个数,每个数为 \(0\) 或 \(1\) 。你可以选择从两边删数,求至少删几个数才可以使剩下的数总和为 \(s\) 。
如果不能达到 \(s\) ,则输出 \(-1\) 。
题目描述
Slavic has an array of length $ n $ consisting only of zeroes and ones. In one operation, he removes either the first or the last element of the array.
What is the minimum number of operations Slavic has to perform such that the total sum of the array is equal to $ s $ after performing all the operations? In case the sum $ s $ can't be obtained after any amount of operations, you should output -1.
输入格式
The first line contains a single integer $ t $ ( $ 1 \leq t \leq 10^4 $ ) — the number of test cases.
The first line of each test case contains two integers $ n $ and $ s $ ( $ 1 \leq n, s \leq 2 \cdot 10^5 $ ) — the length of the array and the needed sum of elements.
The second line of each test case contains $ n $ integers $ a_i $ ( $ 0 \leq a_i \leq 1 $ ) — the elements of the array.
It is guaranteed that the sum of $ n $ over all test cases doesn't exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, output a single integer — the minimum amount of operations required to have the total sum of the array equal to $ s $ , or -1 if obtaining an array with sum $ s $ isn't possible.
样例 #1
样例输入 #1
7
3 1
1 0 0
3 1
1 1 0
9 3
0 1 0 1 1 1 0 0 1
6 4
1 1 1 1 1 1
5 1
0 0 1 1 0
16 2
1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 1
6 3
1 0 1 0 0 0
样例输出 #1
0
1
3
2
2
7
-1
提示
In the first test case, the sum of the whole array is $ 1 $ from the beginning, so we don't have to make any operations.
In the second test case, the sum of the array is $ 2 $ and we want it to be equal to $ 1 $ , so we should remove the first element. The array turns into $ [1, 0] $ , which has a sum equal to $ 1 $ .
In the third test case, the sum of the array is $ 5 $ and we need it to be $ 3 $ . We can obtain such a sum by removing the first two elements and the last element, doing a total of three operations. The array turns into $ [0, 1, 1, 1, 0, 0] $ , which has a sum equal to $ 3 $ .
代码:
#include<iostream>
#include<cstring>
#include<climits>
using namespace std;
const int N = 2e5 + 10;
int a[N];
void solve() {
int n, s;
cin >> n >> s;
memset(a, 0, sizeof(a));
int sum = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
sum += a[i];
}
if (sum < s) {
cout << -1 << endl;
return;
}
if (sum == s) {
cout << 0 << endl;
return;
}
//现在我的总和为sum,目标和为s,至少要删除sum-s次(理想状况,因为不可能删除的都是1)
//肯定是一个动态的过程,我们需要找出最少的操作次数
sum = a[1];
int l = 1, r = 1, ans = INT_MAX;
while (l <= n && r <= n) {
if(sum==s){
ans = min(ans, l - r - 1 + n);
r++;
sum += a[r];
}
if (sum > s) {
sum -= a[l];
l++;
}
if (sum < s) {
sum += a[++r];
}
}
cout << ans << endl;
}
int main()
{
int t; cin >> t;
while (t--) {
solve();
}
return 0;
}
15.Money Trees
题面翻译
Money Trees - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
有 \(n\) 棵树,每棵树高 \(h_i\),有 \(a_i\) 个果子。
你可以选一对 \(l\) 和 \(r\),使得 \(h_{i+1}\mid h_i\space(l\le i<r)\) 且 \(a_l+a_{l+1}+\dots +a_r\le k\)。
求 \(r-l+1\) 的最大值。
By @Larryyu
题目描述
Luca is in front of a row of $ n $ trees. The $ i $ -th tree has $ a_i $ fruit and height $ h_i $ .
He wants to choose a contiguous subarray of the array $ [h_l, h_{l+1}, \dots, h_r] $ such that for each $ i $ ( $ l \leq i < r $ ), $ h_i $ is divisible $ ^{\dagger} $ by $ h_{i+1} $ . He will collect all the fruit from each of the trees in the subarray (that is, he will collect $ a_l + a_{l+1} + \dots + a_r $ fruits). However, if he collects more than $ k $ fruits in total, he will get caught.
What is the maximum length of a subarray Luca can choose so he doesn't get caught?
$ ^{\dagger} $ $ x $ is divisible by $ y $ if the ratio $ \frac{x}{y} $ is an integer.
输入格式
The first line contains a single integer $ t $ ( $ 1 \leq t \leq 1000 $ ) — the number of test cases.
The first of each test case line contains two space-separated integers $ n $ and $ k $ ( $ 1 \leq n \leq 2 \cdot 10^5 $ ; $ 1 \leq k \leq 10^9 $ ) — the number of trees and the maximum amount of fruits Luca can collect without getting caught.
The second line of each test case contains $ n $ space-separated integers $ a_i $ ( $ 1 \leq a_i \leq 10^4 $ ) — the number of fruits in the $ i $ -th tree.
The third line of each test case contains $ n $ space-separated integers $ h_i $ ( $ 1 \leq h_i \leq 10^9 $ ) — the height of the $ i $ -th tree.
The sum of $ n $ over all test cases does not exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case output a single integer, the length of the maximum length contiguous subarray satisfying the conditions, or $ 0 $ if there is no such subarray.
样例 #1
样例输入 #1
5
5 12
3 2 4 1 8
4 4 2 4 1
4 8
5 4 1 2
6 2 3 1
3 12
7 9 10
2 2 4
1 10
11
1
7 10
2 6 3 1 5 10 6
72 24 24 12 4 4 2
样例输出 #1
3
2
1
0
3
提示
In the first test case, Luca can select the subarray with $ l=1 $ and $ r=3 $ .
In the second test case, Luca can select the subarray with $ l=3 $ and $ r=4 $ .
In the third test case, Luca can select the subarray with $ l=2 $ and $ r=2 $ .
代码:
#include<iostream>
#include<cstring>
#define int long long
const int N = 2e5 + 10;
int a[N], s[N], h[N];
using namespace std;
void solve() {
int n, k; cin >> n >> k;
memset(a, 0, sizeof(a)); memset(s, 0, sizeof(s)); memset(h, 0, sizeof(h));
for (int i = 1; i <= n; i++) {
cin >> a[i];
s[i] = s[i - 1] + a[i];
}
for (int i = 1; i <= n; i++) cin >> h[i];
int ans = 0;
for (int i = 1,l=1,r; i <= n; i++) {
r = i;
if (h[i - 1] % h[i]) l = r;
while (s[r] - s[l - 1] > k) l++;
ans = max(ans, r - l + 1);
}
cout << ans << endl;
}
signed main()
{
int t; cin >> t;
while (t--) solve();
return 0;
}
16.Getting Points
Getting Points - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题面翻译
一个学期共 \(n\) 天,每天都会有一节课程,每周第一天会有一次作业,作业可以随时做。
学习课程之后就可以做作业,最多只能做 \(2\) 次作业。
Monocarp 在这一学期想要休息最多的天数以使得他能在学期结束之前达到 \(p\) 分(休息的话就不能上课和做作业),请问他最多能休息多少天。
题目描述
Monocarp is a student at Berland State University. Due to recent changes in the Berland education system, Monocarp has to study only one subject — programming.
The academic term consists of $ n $ days, and in order not to get expelled, Monocarp has to earn at least $ P $ points during those $ n $ days. There are two ways to earn points — completing practical tasks and attending lessons. For each practical task Monocarp fulfills, he earns $ t $ points, and for each lesson he attends, he earns $ l $ points.
Practical tasks are unlocked "each week" as the term goes on: the first task is unlocked on day $ 1 $ (and can be completed on any day from $ 1 $ to $ n $ ), the second task is unlocked on day $ 8 $ (and can be completed on any day from $ 8 $ to $ n $ ), the third task is unlocked on day $ 15 $ , and so on.
Every day from $ 1 $ to $ n $ , there is a lesson which can be attended by Monocarp. And every day, Monocarp chooses whether to study or to rest the whole day. When Monocarp decides to study, he attends a lesson and can complete no more than $ 2 $ tasks, which are already unlocked and not completed yet. If Monocarp rests the whole day, he skips a lesson and ignores tasks.
Monocarp wants to have as many days off as possible, i. e. he wants to maximize the number of days he rests. Help him calculate the maximum number of days he can rest!
输入格式
The first line contains a single integer $ tc $ ( $ 1 \le tc \le 10^4 $ ) — the number of test cases. The description of the test cases follows.
The only line of each test case contains four integers $ n $ , $ P $ , $ l $ and $ t $ ( $ 1 \le n, l, t \le 10^9 $ ; $ 1 \le P \le 10^{18} $ ) — the number of days, the minimum total points Monocarp has to earn, the points for attending one lesson and points for completing one task.
It's guaranteed for each test case that it's possible not to be expelled if Monocarp will attend all lessons and will complete all tasks.
输出格式
For each test, print one integer — the maximum number of days Monocarp can rest without being expelled from University.
样例 #1
样例输入 #1
5
1 5 5 2
14 3000000000 1000000000 500000000
100 20 1 10
8 120 10 20
42 280 13 37
样例输出 #1
0
12
99
0
37
提示
In the first test case, the term lasts for $ 1 $ day, so Monocarp should attend at day $ 1 $ . Since attending one lesson already gives $ 5 $ points ( $ 5 \ge P $ ), so it doesn't matter, will Monocarp complete the task or not.
In the second test case, Monocarp can, for example, study at days $ 8 $ and $ 9 $ : at day $ 8 $ he will attend a lesson for $ 10^9 $ points and complete two tasks for another $ 5 \cdot 10^8 + 5 \cdot 10^8 $ points. And at day $ 9 $ he only attends a lesson for another $ 10^9 $ points.
In the third test case, Monocarp can, for example, study at day $ 42 $ : attending a lesson gives him $ 1 $ point and solving $ 2 $ out of $ 6 $ available tasks gives him another $ 2 \cdot 10 $ points.
In the fourth test case, Monocarp has to attend all lessons and complete all tasks to get $ 8 \cdot 10 + 2 \cdot 20 = 120 $ points.
In the fifth test case, Monocarp can, for example, study at days: $ 8 $ — one lesson and first and second tasks; $ 15 $ — one lesson and the third task; $ 22 $ — one lesson and the fourth task; $ 29 $ — one lesson and the fifth task; $ 36 $ — one lesson and the sixth task.
代码:
#include<iostream>
#include<cstring>
using namespace std;
#define int long long
bool check(int x,int n,int p,int l,int t) {
int ans = 0;
int cnt = n / 7+(n%7!=0);
ans += (n - x) * l;
//分为两种情况,2*x>=cnt,可以做完所有任务,否则,只能做完2*x个任务
if (2 * (n-x) >= cnt) ans += (cnt * t);
else ans += (2*(n-x)) * t;
return ans >= p;
}
int find(int n, int p, int l, int t)
{
int l1 = 0, r = n + 1;
while (l1 + 1 < r) {
int mid = (l1 + r) / 2;
if (check(mid,n,p,l,t)) l1 = mid;
else r = mid;
}
return l1;
}
void solve() {
int n, p, l, t;
cin >> n >> p >> l >> t;
cout << find(n, p, l, t) << endl;
}
signed main()
{
int t; cin >> t;
while (t--) {
solve();
}
return 0;
}
17.Kalindrome Array
Kalindrome Array - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题面翻译
对于长度为 \(m\) 的序列 \(b\),我们称 \(b\) 是「回文的」,当且仅当对于所有 \(i\in[1,m]\),都有 \(b_i=b_{m-i+1}\)。特别的,空序列也是回文的。
对于一个序列,我们称其是「可爱的」,当且仅当且满足如下条件:
- 存在数 \(x\),使得删除序列中若干值等于 \(x\) 的元素后,序列是回文的。(删除元素后,剩余元素会并在一起)
需要注意的是,你并不需要删除所有值等于 \(x\) 的元素,并且,你也可以选择不删除任何元素。
例如:
- \([1,2,1]\) 是可爱的,因为你不需要删除任何一个数,其本身就是回文的。
- \([3,1,2,3,1]\) 是可爱的,因为你可以选择 \(x=3\),然后删除所有值等于 \(3\) 的元素,将其变为回文的。
- \([1,2,3]\) 则不是可爱的。
现在蓝给出了一个长度为 \(n\) 的序列 \(a\),她希望你能帮她确定其是否是可爱的。
本题多组数据,数据组数为 \(t\),会在输入的开头给出。对于每组数据,如果给出的序列 \(a\) 是可爱的,请输出 YES
,否则输出 NO
。
题目数据满足:\(1 \leq t \leq 10^4\),\(1 \leq n \leq 2\times10^5\),\(1 \leq a_i \leq n\),\(1 \leq \sum n \leq 2\times10^5\)。
题目描述
An array $ [b_1, b_2, \ldots, b_m] $ is a palindrome, if $ b_i = b_{m+1-i} $ for each $ i $ from $ 1 $ to $ m $ . Empty array is also a palindrome.
An array is called kalindrome, if the following condition holds:
- It's possible to select some integer $ x $ and delete some of the elements of the array equal to $ x $ , so that the remaining array (after gluing together the remaining parts) is a palindrome.
Note that you don't have to delete all elements equal to $ x $ , and you don't have to delete at least one element equal to $ x $ .
For example :
- $ [1, 2, 1] $ is kalindrome because you can simply not delete a single element.
- $ [3, 1, 2, 3, 1] $ is kalindrome because you can choose $ x = 3 $ and delete both elements equal to $ 3 $ , obtaining array $ [1, 2, 1] $ , which is a palindrome.
- $ [1, 2, 3] $ is not kalindrome.
You are given an array $ [a_1, a_2, \ldots, a_n] $ . Determine if $ a $ is kalindrome or not.
输入格式
The first line contains a single integer $ t $ ( $ 1 \le t \le 10^4 $ ) — the number of test cases. The description of the test cases follows.
The first line of each test case contains a single integer $ n $ ( $ 1 \le n \le 2 \cdot 10^5 $ ) — the length of the array.
The second line of each test case contains $ n $ integers $ a_1, a_2, \ldots, a_n $ ( $ 1 \le a_i \le n $ ) — elements of the array.
It's guaranteed that the sum of $ n $ over all test cases won't exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, print YES if $ a $ is kalindrome and NO otherwise. You can print each letter in any case.
样例 #1
样例输入 #1
4
1
1
2
1 2
3
1 2 3
5
1 4 4 1 4
样例输出 #1
YES
YES
NO
YES
提示
In the first test case, array $ [1] $ is already a palindrome, so it's a kalindrome as well.
In the second test case, we can choose $ x = 2 $ , delete the second element, and obtain array $ [1] $ , which is a palindrome.
In the third test case, it's impossible to obtain a palindrome.
In the fourth test case, you can choose $ x = 4 $ and delete the fifth element, obtaining $ [1, 4, 4, 1] $ . You also can choose $ x = 1 $ , delete the first and the fourth elements, and obtain $ [4, 4, 4] $ .
代码:
#include<iostream>
#include<cstring>
using namespace std;
const int N = 2e5 + 10;
int a[N], tmp[N];
bool ishuiwen(int n, int b[])
{
for (int i = 1; i <= n; i++) {
if (b[i] != b[n - i + 1]) return false;
}
return true;
}
bool check(int x,int n)
{
int index = 0;
for (int i = 1; i <= n; i++) {
if (a[i] != x) tmp[++index] = a[i];
}
return ishuiwen(index, tmp);
}
void solve() {
int n; cin >> n;
memset(a, 0, sizeof(a)); memset(tmp, 0, sizeof(tmp));
for (int i = 1; i <= n; i++) cin >> a[i];
if (ishuiwen(n, a)) {
cout << "YES" << endl;
return;
}
int l = 1, r = n,x=1,y=r;
while (l <= r) {
if (a[l] != a[r]) {
x = a[l],y=a[r];
break;
}
l++; r--;
}
if (check(x,n) || check(y,n)) {
cout << "YES" << endl;
}
else cout << "NO" << endl;
return;
}
int main()
{
int t; cin >> t;
while (t--) solve();
return 0;
}
18.Boats Competition
Boats Competition - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题面翻译
有 \(n\) 个人要参与两人一组的划船比赛,第 \(i\) 个人的质量为 \(w_i\) 。
作为比赛的组织者,你希望通过这样的方式使得比赛公平:每队的两位选手的质量和都相等。
即,如果有 \(k\) 组,第 \(i\) 组的两位选手的质量分别为 \((a_i,b_i)\) ,那么需要满足以下条件:
\(a_1+b_1=a_2+b_2=...=a_k+b_k=s\)
你需要找到这样的一个 \(s\) ,使得队伍数( \(k\) )尽可能多。
题目描述
There are $ n $ people who want to participate in a boat competition. The weight of the $ i $ -th participant is $ w_i $ . Only teams consisting of two people can participate in this competition. As an organizer, you think that it's fair to allow only teams with the same total weight.
So, if there are $ k $ teams $ (a_1, b_1) $ , $ (a_2, b_2) $ , $ \dots $ , $ (a_k, b_k) $ , where $ a_i $ is the weight of the first participant of the $ i $ -th team and $ b_i $ is the weight of the second participant of the $ i $ -th team, then the condition $ a_1 + b_1 = a_2 + b_2 = \dots = a_k + b_k = s $ , where $ s $ is the total weight of each team, should be satisfied.
Your task is to choose such $ s $ that the number of teams people can create is the maximum possible. Note that each participant can be in no more than one team.
You have to answer $ t $ independent test cases.
输入格式
The first line of the input contains one integer $ t $ ( $ 1 \le t \le 1000 $ ) — the number of test cases. Then $ t $ test cases follow.
The first line of the test case contains one integer $ n $ ( $ 1 \le n \le 50 $ ) — the number of participants. The second line of the test case contains $ n $ integers $ w_1, w_2, \dots, w_n $ ( $ 1 \le w_i \le n $ ), where $ w_i $ is the weight of the $ i $ -th participant.
输出格式
For each test case, print one integer $ k $ : the maximum number of teams people can compose with the total weight $ s $ , if you choose $ s $ optimally.
样例 #1
样例输入 #1
5
5
1 2 3 4 5
8
6 6 6 6 6 6 8 8
8
1 2 2 1 2 1 1 2
3
1 3 3
6
1 1 3 4 2 2
样例输出 #1
2
3
4
1
2
提示
In the first test case of the example, we can reach the optimal answer for $ s=6 $ . Then the first boat is used by participants $ 1 $ and $ 5 $ and the second boat is used by participants $ 2 $ and $ 4 $ (indices are the same as weights).
In the second test case of the example, we can reach the optimal answer for $ s=12 $ . Then first $ 6 $ participants can form $ 3 $ pairs.
In the third test case of the example, we can reach the optimal answer for $ s=3 $ . The answer is $ 4 $ because we have $ 4 $ participants with weight $ 1 $ and $ 4 $ participants with weight $ 2 $ .
In the fourth test case of the example, we can reach the optimal answer for $ s=4 $ or $ s=6 $ .
In the fifth test case of the example, we can reach the optimal answer for $ s=3 $ . Note that participant with weight $ 3 $ can't use the boat because there is no suitable pair for him in the list.
代码:
#include<iostream>
#include<vector>
using namespace std;
void solve() {
int n;
cin >> n;
vector<int> cnt(n + 1);
// 使用一个临时变量来存储原始的 n
for (int i = 0; i < n; i++) {
int x; cin >> x;
++cnt[x];
}
int ans = 0;
for (int s = 2; s <= 2 * n; s++) {
int k = 0;
for (int i = 1; i < (s + 1) / 2; i++) {
// 枚举从1-s/2所有能组成s的对数
if (s - i > n) continue;
k += min(cnt[i], cnt[s - i]);
}
if (s % 2 == 0) k += cnt[s / 2] / 2;
ans = max(k, ans);
}
cout << ans << endl;
}
int main() {
int t;
cin >> t;
while (t--) solve();
return 0;
}