Codeforces Round #708 (Div. 2)
Codeforces Round #708 (Div. 2)
没有正式参加(又划水), 这场比赛unrated。 从比赛结果看, 题目似乎不是很难.
A题 Meximization
原题链接
题意:
给定一个数组\(a\), 对该数组重新排序得到\(b\), 使得\(\sum_{i=0}^NMEX(b_{1}...b_{i})\)最大, 其中\(MEX\)是指所有数中没有出现的最小非负整数.
思路:
贪心, 尽量把小的数向前填, 同时保证不出现重复数字, 即构造\(b\)前面部分为\(a\)中数字从小到大排序后的数字(不重复), 剩下部分为\(a\)中重复出现的数字.
#include
#include
#include
#include
B题 M-arrays
原题链接
题意:
给定数组\(a\)和\(m\), 对\(a\)中元素重新分组, 使得每一组中相邻两个元素都能被\(m\)整除, 求一种分组方法,使得组数最小.(单独一个数认为可以被\(m\)整除)
思路:
构造, 使用数组\(cnt[]\), \(cnt[i]\) 记录数字i出现次数, 将每个数对\(m\)取模, 并将结果\(i\)对应的\(cnt[i] ++\), 遍历 \(1 -> m\), 对\(cnt[i]\) 与 \(cnt[m - i]\) 进行处理.
设 $ i = x mod m $, \(j = y mod m\) , 易知, 当 \(i + j = m\) 时, \(x + y\)一定可以被\(m\)整除.据此进行构造.
#include
#include
#include
C1题 k-LCM (easy version)
原题链接
题意:
给定数字\(n\), \(k\)(\(k = 3\)), 构造\(k\)个数, 使得这\(k\)个数和为\(n\),且最小公倍数小于等于\(n / 2\)
思路:
(感觉比B简单), 分三种情况:
- \(n\)为奇数, 构造三个数为\(1,(n - 1) / 2,(n - 1)/2\)
- \(n\)能被2和4整除: \(n / 2,n / 4,n / 4\)
- \(n\)能被2整除,不能被4整除: \(2,(n - 2)/2,(n - 2)/2\)
#include
#include
using namespace std;
void solve()
{
int n, k;
cin >> n >> k;
if (n % 2){
int t = (n - 1) / 2;
printf("%d %d %d\n", 1, t, t);
}else{
if (n % 4 == 0){
printf("%d %d %d\n", n / 2, n / 4, n / 4);
}else{
int t = (n - 2) / 2;
printf("%d %d %d\n", 2, t, t);
}
}
return ;
}
int main()
{
int t;
cin >> t;
while (t -- )
solve();
return 0;
}
C2题 k-LCM (hard version)
原题链接
题意:
和C1不同就是\(k\)未知,但满足\(3\leq k\leq n\)
思路:
将\(k - 3\)个数全部设为\(1\), 剩下\(3\)个数和C1题一样
#include
#include
using namespace std;
const int N = 1e5 + 10;
void solve()
{
int n, k;
cin >> n >> k;
for (int i = 1; i <= k - 3; i ++ ){
cout << 1 << ' ';
n--;
}
if (n % 2){
int t = (n - 1) / 2;
printf("%d %d %d\n", 1, t, t);
}else{
if (n % 4 == 0){
printf("%d %d %d\n", n / 2, n / 4, n / 4);
}else{
int t = (n - 2) / 2;
printf("%d %d %d\n", 2, t, t);
}
}
}
int main()
{
int t;
cin >> t;
while (t -- )
solve();
return 0;
}