🚀欢迎来到本文🚀
🍉个人简介:陈童学哦,彩笔ACMer一枚。
🏀所属专栏:Codeforces
本文用于记录回顾本彩笔的解题思路便于加深理解。
You are given three points with integer coordinates x 1 x_1 x1, x 2 x_2 x2, and x 3 x_3 x3 on the X X X axis ( 1 ≤ x i ≤ 10 1 \leq x_i \leq 10 1≤xi≤10). You can choose any point with an integer coordinate a a a on the X X X axis. Note that the point a a a may coincide with x 1 x_1 x1, x 2 x_2 x2, or x 3 x_3 x3. Let f ( a ) f(a) f(a) be the total distance from the given points to the point a a a. Find the smallest value of f ( a ) f(a) f(a).
The distance between points a a a and b b b is equal to ∣ a − b ∣ |a - b| ∣a−b∣. For example, the distance between points a = 5 a = 5 a=5 and b = 2 b = 2 b=2 is 3 3 3.
Input
Each test consists of multiple test cases. The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 3 1 \leq t \leq 10^3 1≤t≤103) — the number of test cases. Then follows their descriptions.
The single line of each test case contains three integers x 1 x_1 x1, x 2 x_2 x2, and x 3 x_3 x3 ( 1 ≤ x i ≤ 10 1 \leq x_i \leq 10 1≤xi≤10) — the coordinates of the points.
Output
For each test case, output the smallest value of f ( a ) f(a) f(a).
可以通过暴力枚举出来最佳的那个点,然后计算答案,但是这里我们其实可以发现f(a)的最小值其实就是a为x1、x2、x3三个点中从小到大排序中间的那个点。
#include
#define look(x) cout << #x << " == " << x << "\n"
using namespace std;
using i64 = long long;
using ld = long double;
const int N = 2e5 + 10;
const int MOD1 = 1e9 + 7;
const int MOD2 = 998244353;
void solve(){
int a[3];
cin >> a[0] >> a[1] >> a[2];
sort(a,a + 3);
cout << a[1] - a[0] + a[2] - a[1] << "\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
cin >> t;
while(t --){
solve();
}
return 0;
}
You are given a matrix of size n × m n \times m n×m, where the rows are numbered from 1 1 1 to n n n from top to bottom, and the columns are numbered from 1 1 1 to m m m from left to right. The element at the intersection of the i i i-th row and the j j j-th column is denoted by a i j a_{ij} aij.
Consider the algorithm for stabilizing matrix a a a:
In this problem, cells ( a , b ) (a, b) (a,b) and ( c , d ) (c, d) (c,d) are considered neighbors if they share a common side, i.e., ∣ a − c ∣ + ∣ b − d ∣ = 1 |a - c| + |b - d| = 1 ∣a−c∣+∣b−d∣=1.
Your task is to output the matrix a a a after the stabilization algorithm has been executed. It can be shown that this algorithm cannot run for an infinite number of iterations.
Input
Each test consists of multiple sets of input data. The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1≤t≤104) — the number of sets of input data. This is followed by their description.
The first line of each set of input data contains two integers n n n and m m m (KaTeX parse error: Expected 'EOF', got '&' at position 33: …100, n \cdot m &̲gt; 1) — the number of rows and columns of matrix a a a.
The next n n n lines describe the corresponding rows of the matrix. The i i i-th line contains m m m integers a i 1 , a i 2 , … , a i m a_{i1}, a_{i2}, \ldots, a_{im} ai1,ai2,…,aim ( 1 ≤ a i j ≤ 1 0 9 1 \leq a_{ij} \leq 10^9 1≤aij≤109).
It is guaranteed that the sum of n ⋅ m n \cdot m n⋅m over all sets of input data does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.
Output
For each set of input data, output n n n lines with m m m numbers in each line — the values of the cells of matrix a a a after the stabilization algorithm.
从上往下从左往右依次遍历,如果当前数满足条件(严格大于它上、下、左、右的四个数)时,就将当前数设置为它上、下、左、右的四个数中的最大值。
#include
#define look(x) cout << #x << " == " << x << "\n"
using namespace std;
using i64 = long long;
using ld = long double;
const int N = 2e5 + 10;
const int MOD1 = 1e9 + 7;
const int MOD2 = 998244353;
int g[110][110];
void solve(){
int n,m;
cin >> n >> m;
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= m;j ++){
cin >> g[i][j];
}
}
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= m;j ++){
if(g[i][j] > g[i - 1][j] && g[i][j] > g[i + 1][j] && g[i][j] > g[i][j + 1] && g[i][j] > g[i][j - 1]){
g[i][j] = max({g[i - 1][j],g[i + 1][j],g[i][j - 1],g[i][j + 1]});
}
}
}
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= m;j ++){
cout << g[i][j] << " ";
}
cout << "\n";
}
for(int i = 0;i < 110;i ++){
for(int j = 0;j < 110;j ++){
g[i][j] = 0;
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
cin >> t;
while(t --){
solve();
}
return 0;
}
Let’s consider the following simple problem. You are given a string s s s of length n n n, consisting of lowercase Latin letters, as well as an array of indices i n d ind ind of length m m m ( 1 ≤ i n d i ≤ n 1 \leq ind_i \leq n 1≤indi≤n) and a string c c c of length m m m, consisting of lowercase Latin letters. Then, in order, you perform the update operations, namely, during the i i i-th operation, you set s i n d i = c i s_{ind_i} = c_i sindi=ci. Note that you perform all m m m operations from the first to the last.
Of course, if you change the order of indices in the array i n d ind ind and/or the order of letters in the string c c c, you can get different results. Find the lexicographically smallest string s s s that can be obtained after m m m update operations, if you can rearrange the indices in the array i n d ind ind and the letters in the string c c c as you like.
A string a a a is lexicographically less than a string b b b if and only if one of the following conditions is met:
Input
Each test consists of several sets of input data. The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1≤t≤104) — the number of sets of input data. Then follows their description.
The first line of each set of input data contains two integers n n n and m m m ( 1 ≤ n , m ≤ 1 0 5 1 \leq n, m \leq 10^5 1≤n,m≤105) — the length of the string s s s and the number of updates.
The second line of each set of input data contains a string s s s of length n n n, consisting of lowercase Latin letters.
The third line of each set of input data contains m m m integers i n d 1 , i n d 2 , … , i n d m ind_1, ind_2, \ldots, ind_m ind1,ind2,…,indm ( 1 ≤ i n d i ≤ n 1 \leq ind_i \leq n 1≤indi≤n) — the array of indices i n d ind ind.
The fourth line of each set of input data contains a string c c c of length m m m, consisting of lowercase Latin letters.
It is guaranteed that the sum of n n n over all sets of input data does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105. Similarly, the sum of m m m over all sets of input data does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.\
Output
For each set of input data, output the lexicographically smallest string s s s that can be obtained by rearranging the indices in the array i n d ind ind and the letters in the string c c c as you like.
我们想得到字典序最小的字符串,首先的话我们肯定是尽量想让字符串c中字典序小的字母尽可能的去替换原字符串索引位置靠前的字母,这样才能保证字典序最小,但是我们需要考虑到问题就是题目所给的索引数组ind中的数可能是相等的,也就意味着如果出现两个相同索引连续出现两次以上的话,当我们先去用字符串c中字典序更小的字母去替换的时候下次再次替换时会导致这个地方的字典序不是最小的。那么考虑如何解决这个弊端呢,这里可以考虑使用双指针,当出现两个相同以上的索引时,我们可以先从字符串c的尾指针先开始替换,这样就能保证下次替换的时候是字典序更小的字母替换更大的,而不是字典序小的被字典序大的替换掉。
#include
#define look(x) cout << #x << " == " << x << "\n"
using namespace std;
using i64 = long long;
using ld = long double;
const int N = 2e5 + 10;
const int MOD1 = 1e9 + 7;
const int MOD2 = 998244353;
void solve(){
int n,m;
cin >> n >> m;
string s1,s2;
cin >> s1;
int n1 = s1.size();
s1 = '?' + s1;
// look(s1);
vector<int> a(m + 1);
for(int i = 1;i <= m;i ++){
cin >> a[i];
}
cin >> s2;
int n2 = s2.size();
sort(s2.begin(),s2.end());
// look(s2);
s2 = '?' + s2;
// look(s2);
sort(a.begin() + 1,a.end());
int l = 1,r = n2;
// look(a[1]);
// look(a[2]);
for(int i = 1;i <= m;i ++){
if(i != m && a[i] == a[i + 1]){
// look(s1);
s1[a[i]] = s2[r];
r --;
}
if(i == m){
s1[a[i]] = s2[l];
break;
}
if(a[i] != a[i + 1]){
// look(i);
// look(s1);
s1[a[i]] = s2[l];
l ++;
}
}
// look(s1);
cout << s1.substr(1,n1) << "\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
cin >> t;
while(t --){
solve();
}
return 0;
}
You are given a string s s s of length KaTeX parse error: Expected 'EOF', got '&' at position 3: n &̲gt; 1, consisting of digits from 0 0 0 to 9 9 9. You must insert exactly n − 2 n - 2 n−2 symbols + + + (addition) or × \times × (multiplication) into this string to form a valid arithmetic expression.
In this problem, the symbols cannot be placed before the first or after the last character of the string s s s, and two symbols cannot be written consecutively. Also, note that the order of the digits in the string cannot be changed. Let’s consider s = 987009 s = 987009 s=987009:
The result of the arithmetic expression is calculated according to the rules of mathematics — first all multiplication operations are performed, then addition. You need to find the minimum result that can be obtained by inserting exactly n − 2 n - 2 n−2 addition or multiplication symbols into the given string s s s.
Input
Each test consists of multiple test cases. The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1≤t≤104) — the number of test cases. Then follows their description.
The first line of each test case contains a single integer n n n ( 2 ≤ n ≤ 20 2 \leq n \leq 20 2≤n≤20) — the length of the string s s s.
The second line of each test case contains a string s s s of length n n n, consisting of digits from 0 0 0 to 9 9 9.
Output
For each test case, output the minimum result of the arithmetic expression that can be obtained by inserting exactly n − 2 n - 2 n−2 addition or multiplication symbols into the given string.
长度为n的字符串插入n-2个符号,首先n为2是就是当前字符串转换为十进制数的结果,否则的话就是n-1个数字与n-2个符号之间的运算,n个字符组成n-1个数,显然必有一个数为两位数其余都为一位数,那么当n > 2时我们可以从左往右依次枚举相邻两位组成一个两位数时的与其他数进行加、乘运算的最小值,如果有0出现那么最小值必然为0,其次有1出现的话相乘能让结果不变,其余数均相加即可让值最小,最后在枚举的所有情况中取最小值即位答案。
#include
#define look(x) cout << #x << " == " << x << "\n"
using namespace std;
using i64 = long long;
using ld = long double;
const int N = 2e5 + 10;
const int MOD1 = 1e9 + 7;
const int MOD2 = 998244353;
void solve(){
int n;
cin >> n;
string s;
cin >> s;
if(n == 2){
cout << stoi(s) << "\n";
return;
}
int ans = 1e9;
map<int,int> mp;
for(int i = 0;i < n - 1;i ++){
int x = stoi(s.substr(i,2));
int sum = 0;
sum += x;
mp[i] = 1;
mp[i + 1] = 1;
for(int i = 0;i < n;i ++){
if(!mp[i]){
int y = (s[i] - '0');
if(y == 0){
cout << "0\n";
return;
}
if(sum == 1){
sum *= y;
continue;
}
if(y != 1){
sum += y;
}
}
}
ans = min(ans,sum);
mp.clear();
}
cout << ans << "\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
cin >> t;
while(t --){
solve();
}
return 0;
}
You are given an array of integers a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,…,an and an integer k k k. You need to make it beautiful with the least amount of operations.
Before applying operations, you can shuffle the array elements as you like. For one operation, you can do the following:
The array b 1 , b 2 , … , b n b_1, b_2, \ldots, b_n b1,b2,…,bn is beautiful if b i = b n − i + 1 b_i = b_{n - i + 1} bi=bn−i+1 for all 1 ≤ i ≤ n 1 \leq i \leq n 1≤i≤n.
Find the minimum number of operations needed to make the array beautiful, or report that it is impossible.
Input
Each test consists of several sets of input data. The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1≤t≤104) — the number of sets of input data. Then follows their description.
The first line of each set of input data contains two integers n n n and k k k ( 1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1≤n≤105, 1 ≤ k ≤ 1 0 9 1 \leq k \leq 10^9 1≤k≤109) — the size of the array a a a and the number k k k from the problem statement.
The second line of each set of input data contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,…,an ( 1 ≤ a i ≤ 1 0 9 1 \leq a_i \leq 10^9 1≤ai≤109) — the elements of the array a a a.
It is guaranteed that the sum of n n n over all sets of input data does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.
Output
For each set of input data, output the minimum number of operations needed to make the array beautiful, or − 1 -1 −1 if it is impossible.
要构造漂亮数组,首先如果一个数出现的次数如果为偶数的话,我们就不需要进行操作,否则的话我们需要使用一个map里套vector的map
#include
#define look(x) cout << #x << " == " << x << "\n"
using namespace std;
using i64 = long long;
using ld = long double;
const int N = 2e5 + 10;
const int MOD1 = 1e9 + 7;
const int MOD2 = 998244353;
void solve(){
int n,k;
cin >> n >> k;
vector<int> a(n + 1);
map<int,int> mp;
for(int i = 1;i <= n;i ++){
cin >> a[i];
mp[a[i]] ++;
}
map<int,vector<int>> mv;
for(auto [x,y] : mp){
if(y & 1){
mv[x % k].push_back(x);
}
}
i64 ans = 0;
int res = 0;
for(auto [x,y] : mv){
if(y.size() & 1){
res ++;
if(res > 1){
cout << "-1\n";
return;
}
}
sort(y.begin(),y.end());
if(y.size() % 2 == 0){
for(int i = 1;i < y.size();i += 2){
int x = y[i] - y[i - 1];
ans += x / k;
}
}else if(y.size() > 1){
int m = (int)y.size();
vector<i64> sum1(m);
vector<i64> sum2(m);
sum1[1] = y[1] - y[0];
for(int i = 3;i < m;i += 2){
sum1[i] = sum1[i - 2] + y[i] - y[i - 1];
}
sum2[m - 2] = y[m - 1] - y[m - 2];
for(int i = m - 4;i >= 0;i -= 2){
sum2[i] = sum2[i + 2] + y[i + 1] - y[i];
}
i64 tmp = min(sum1[m - 2],sum2[1]);
for(int i = 2;i < m - 2;i += 2){
tmp = min(tmp,sum1[i - 1] + sum2[i + 1]);
}
ans += tmp / k;
}
}
cout << ans << "\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
cin >> t;
while(t --){
solve();
}
return 0;
}