本文主要是介绍Codeforces Round #642 (Div. 3)------题目+题解+代码(A、B、C、D),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- A. Most Unstable Array
- B. Two Arrays And Swaps
- C. Board Moves
- D. Constructing the Array
A. Most Unstable Array
来源:http://codeforces.com/contest/1353/problem/A
You are given two integers n and m. You have to construct the array a of length n consisting of non-negative integers (i.e. integers greater than or equal to zero) such that the sum of elements of this array is exactly m and the value ∑i=1n−1|ai−ai+1| is the maximum possible. Recall that |x| is the absolute value of x.
In other words, you have to maximize the sum of absolute differences between adjacent (consecutive) elements. For example, if the array a=[1,3,2,5,5,0] then the value above for this array is |1−3|+|3−2|+|2−5|+|5−5|+|5−0|=2+1+3+0+5=11. Note that this example doesn’t show the optimal answer but it shows how the required value for some array is calculated.
You have to answer t independent test cases.
Input
The first line of the input contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.
The only line of the test case contains two integers n and m (1≤n,m≤109) — the length of the array and its sum correspondingly.
Output
For each test case, print the answer — the maximum possible value of ∑i=1n−1|ai−ai+1| for the array a consisting of n non-negative integers with the sum m.
Example
inputCopy
5
1 100
2 2
5 5
2 1000000000
1000000000 1000000000
outputCopy
0
2
10
1000000000
2000000000
Note
In the first test case of the example, the only possible array is [100] and the answer is obviously 0.
In the second test case of the example, one of the possible arrays is [2,0] and the answer is |2−0|=2.
In the third test case of the example, one of the possible arrays is [0,2,0,3,0] and the answer is |0−2|+|2−0|+|0−3|+|3−0|=10.
题意:
给你两个数n和m,让你找出n个和为m的数,并且邻位数的差的绝对值最大,并输出最大值。
思路:
毕竟是A题,就超简单的方向上思考,通过观察和结合样例可以发现是有规律可循的
n=1时: ans=0
很显然只有一项时ans为0n=2时: ans=m
只有两项时,两个数只能分为 0 m ,才能实现最大n=3时: ans=2*m
将三个数分为0 m 0,此时最大n>3时: ans=2*m
和n=3时相同,其他项均为零即可
找到规律后,这道题就解决了
代码:
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
int main()
{int t;cin >> t;int n, m;while (t--){cin >> n >> m;if (n == 1)cout << '0' << endl;else if (n == 2)cout << m << endl;else cout << 2 * m << endl;}return 0;
}
B. Two Arrays And Swaps
来源:http://codeforces.com/contest/1353/problem/B
You are given two arrays a and b both consisting of n positive (greater than zero) integers. You are also given an integer k.
In one move, you can choose two indices i and j (1≤i,j≤n) and swap ai and bj (i.e. ai becomes bj and vice versa). Note that i and j can be equal or different (in particular, swap a2 with b2 or swap a3 and b9 both are acceptable moves).
Your task is to find the maximum possible sum you can obtain in the array a if you can do no more than (i.e. at most) k such moves (swaps).
You have to answer t independent test cases.
Input
The first line of the input contains one integer t (1≤t≤200) — the number of test cases. Then t test cases follow.
The first line of the test case contains two integers n and k (1≤n≤30;0≤k≤n) — the number of elements in a and b and the maximum number of moves you can do. The second line of the test case contains n integers a1,a2,…,an (1≤ai≤30), where ai is the i-th element of a. The third line of the test case contains n integers b1,b2,…,bn (1≤bi≤30), where bi is the i-th element of b.
Output
For each test case, print the answer — the maximum possible sum you can obtain in the array a if you can do no more than (i.e. at most) k swaps.
Example
inputCopy
5
2 1
1 2
3 4
5 5
5 5 6 6 5
1 2 5 4 3
5 3
1 2 3 4 5
10 9 10 10 9
4 0
2 2 4 3
2 4 2 3
4 4
1 2 2 1
4 4 5 4
outputCopy
6
27
39
11
17
Note
In the first test case of the example, you can swap a1=1 and b2=4, so a=[4,2] and b=[3,1].
In the second test case of the example, you don’t need to swap anything.
In the third test case of the example, you can swap a1=1 and b1=10, a3=3 and b3=10 and a2=2 and b4=10, so a=[10,10,10,4,5] and b=[1,9,3,2,9].
In the fourth test case of the example, you cannot swap anything.
In the fifth test case of the example, you can swap arrays a and b, so a=[4,4,5,4] and b=[1,2,2,1].
题意:
给你两个长度为n的数组a,b,交换a和b中的元素,并且最多交换k次,是a数组所有元素的和最大。
思路:
贪心的问题,思路比较好想,就是用a数组较小的元素去换b数组中较大的元素,若数组a中最小值小于b中最大值,将其用b中最大值替换,具体实现见代码
代码:
#include<iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[35], b[35];
int cmp(int a, int b)
{return a > b;
}
int main()
{int t, n, k, i, sum;scanf("%d", &t);while (t--) {sum = 0;scanf("%d%d", &n, &k);for (i = 1; i <= n; i++)scanf("%d", &a[i]);for (i = 1; i <= n; i++)scanf("%d", &b[i]);sort(a + 1, a + 1 + n);//升序sort(b + 1, b + 1 + n, cmp);//降序for (i = 1; i <= k; i++){if (a[i] < b[i])swap(a[i], b[i]);elsebreak;}for (i = 1; i <= n; i++)sum += a[i];printf("%d\n", sum);}return 0;
}
C. Board Moves
来源:http://codeforces.com/contest/1353/problem/C
You are given a board of size n×n, where n is odd (not divisible by 2). Initially, each cell of the board contains one figure.
In one move, you can select exactly one figure presented in some cell and move it to one of the cells sharing a side or a corner with the current cell, i.e. from the cell (i,j) you can move the figure to cells:
(i−1,j−1);
(i−1,j);
(i−1,j+1);
(i,j−1);
(i,j+1);
(i+1,j−1);
(i+1,j);
(i+1,j+1);
Of course, you can not move figures to cells out of the board. It is allowed that after a move there will be several figures in one cell.
Your task is to find the minimum number of moves needed to get all the figures into one cell (i.e. n2−1 cells should contain 0 figures and one cell should contain n2 figures).
You have to answer t independent test cases.
Input
The first line of the input contains one integer t (1≤t≤200) — the number of test cases. Then t test cases follow.
The only line of the test case contains one integer n (1≤n<5⋅105) — the size of the board. It is guaranteed that n is odd (not divisible by 2).
It is guaranteed that the sum of n over all test cases does not exceed 5⋅105 (∑n≤5⋅105).
Output
For each test case print the answer — the minimum number of moves needed to get all the figures into one cell.
Example
inputCopy
3
1
5
499993
outputCopy
0
40
41664916690999888
题意:
给你一个n * n的方格,其中每个方格内都有一个数字,它能向周围的八个方格任意移动,现在将所有的数字都移动到一个方格中,问最少需要多少移动步
思路:
很容易就想到最后的点肯定是中心点,然后再仔细观察发现,以中心点为基点,周围的第一圈只需要一步就能移动到中心点,而第二圈需要两步,第三圈需要三步,以此类推,第n圈需要n步。
这样就找到了规律
其中每圈有(i-1)*4个方格,圈数为 i/2
代码:
#include<iostream>
using namespace std;
typedef long long ll;
const ll N = 5e5 + 5;
ll res[N];
int main()
{int t; ll n;cin >> t;for (ll i = 3; i <= N; i = i + 2){res[i] = (i - 1) * 4 * (i / 2);res[i] += res[i - 2];}while (t--){cin >> n;cout << res[n] << endl;}
}
D. Constructing the Array
来源:http://codeforces.com/contest/1353/problem/D
You are given an array a of length n consisting of zeros. You perform n actions with this array: during the i-th action, the following sequence of operations appears:
Choose the maximum by length subarray (continuous subsegment) consisting only of zeros, among all such segments choose the leftmost one;
Let this segment be [l;r]. If r−l+1 is odd (not divisible by 2) then assign (set) a[l+r2]:=i (where i is the number of the current action), otherwise (if r−l+1 is even) assign (set) a[l+r−12]:=i.
Consider the array a of length 5 (initially a=[0,0,0,0,0]). Then it changes as follows:
Firstly, we choose the segment [1;5] and assign a[3]:=1, so a becomes [0,0,1,0,0];
then we choose the segment [1;2] and assign a[1]:=2, so a becomes [2,0,1,0,0];
then we choose the segment [4;5] and assign a[4]:=3, so a becomes [2,0,1,3,0];
then we choose the segment [2;2] and assign a[2]:=4, so a becomes [2,4,1,3,0];
and at last we choose the segment [5;5] and assign a[5]:=5, so a becomes [2,4,1,3,5].
Your task is to find the array a of length n after performing all n actions. Note that the answer exists and unique.
You have to answer t independent test cases.
Input
The first line of the input contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.
The only line of the test case contains one integer n (1≤n≤2⋅105) — the length of a.
It is guaranteed that the sum of n over all test cases does not exceed 2⋅105 (∑n≤2⋅105).
Output
For each test case, print the answer — the array a of length n after performing n actions described in the problem statement. Note that the answer exists and unique.
Example
inputCopy
6
1
2
3
4
5
6
outputCopy
1
1 2
2 1 3
3 1 2 4
2 4 1 3 5
3 4 1 5 2 6
题意:
输入一个n,表示有一个长度为n且全为0的数组。现在需要做出n次操作,操作有两种。
第一种是先选出一个长度最长的连续的0的区间,如果有多个这样的区间且长度相同,选择最左端的一个区间。
第二个操作是,如果该区间的长度为奇数,那么将数组的第(l+r)/2为设为i,如果该区间长度为偶数,将数组的第(l+r-1)/2位设为i。
直到n次操作结束,该数组被填满,有且只有唯一的答案,输出该数组。
思路:
思路首先可以想到模拟,每次去找最符合要求的区间,然后填上数字。
然后想到了用优先队列来模拟这个过程,优先选择区间长度最长的,如果相同,那么就选择最靠左端的,这样就相当于模拟一样的实现了这个过程。
代码:
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
struct Node {int l, r;bool operator <(const Node& a) const {return a.r - a.l == r - l ? a.l < l : a.r - a.l > r - l;}
}cur;
int pre[200005];
int n, T;int main()
{cin>>T;while (T--) {cin >> n;memset(pre, 0, sizeof(pre));priority_queue<Node> q;q.push(Node{ 1, n });for (int i = 1; i <= n; i++) {cur = q.top();q.pop();int mid = (cur.l + cur.r) / 2;pre[mid] = i;if (mid - cur.l != 0) q.push(Node{ cur.l, mid - 1 });if (cur.r - mid != 0) q.push(Node{ mid + 1, cur.r });}for (int i = 1; i <= n; i++) cout<<pre[i]<<' ';cout << endl;}return 0;
}
如有不足之处,请指正~
这篇关于Codeforces Round #642 (Div. 3)------题目+题解+代码(A、B、C、D)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!