Codeforces Round 892 (Div. 2)
A United We Stand
题意:给一个数组,让你把它分成两个数组,第二个数组里的数不能是第一个数组里的数的除数,先输出两个数组的长度,依次输出两个数组的数,如果无法分出来,输出-1
思路:如果数的种类只有一种一定不行,反之一定行,对于可行的情况,我们把最大的数放在第二部分,其他的数放在第一部分,一定满足条件
void solve() {
int n;
cin >> n;
vector<int> a(n);
map<int, int> mp;
for(auto &i : a)cin >> i, mp[i]++;
sort(rALL(a));
if(mp.size() == 1)cout << -1 << endl;
else {
cout << n - mp[a[0]] << ' ' << mp[a[0]] << endl;
for(auto i : a)if(i != a[0])cout << i << ' ';
cout << endl;
for(auto i : a)if(i == a[0])cout << i << ' ';
cout << endl;
}
}
B Olya and Game with Arrays
题意:给一个类似二维数组,但是不规则,通过无限次操作使得每一行最小的数的和最大,操作:最多可以将一个(可能是 0 )整数从每个数组移动到另一个数组。需要注意的是,整数只能从一个数组中移动一次,但整数可以添加到一个数组中多次,而且所有移动都是同时完成的
思路:要是总和最大,尽可能是每一行的最小值最大,而所有数的最小一定固定占据一行,而每一个数最多移动一次,所以我们把每一行的最小的数移到一行,其他行的次小值就变成最小值,一定是最优的,总而言之就是所有数的最小值\(+\)每一行的次小值\(-\)每一行次小值的最小的那个就是答案
void solve() {
int n;
cin >> n;
int mn = INT_MAX;
vector<int> ans;
for(int i = 0; i < n; i++) {
int m;
cin >> m;
vector<int> a(m);
for(auto &j : a)cin >> j;
sort(ALL(a));
mn = min(mn, a[0]);
ans.push_back(a[1]);
}
sort(rALL(ans));
int sum = mn;
for(int i = 0; i < n - 1; i++)sum += ans[i];
cout << sum << endl;
}
C Another Permutation Problem
题意:找到一个\(n\)的排列\(p\),满足:\((\sum_{i = 1}^{n} p_i \cdot i) - (\max_{j = 1}^{n} p_j \cdot j)\)
思路:看见排列,我直接打表,打表的代码和图片如下,我们可以发现最优解的排列只是在\(n,n-1,n-2,n-3,\dots,1\)的基础上向右移动获得的,我们可以暴力的去枚举每一中情况,时间复杂度:\(O(n)\),而且此题数据范围只有250,妥妥的
void solve() {
int n;
cin >> n;
int sum = 0;
int ans = 0;
int mx = 0;
for(int i = 0; i < n; i++) {
sum = 0;
mx = 0;
for(int j = 1; j <= i; j++) {
sum += j * j;
mx = max(mx, j * j);
}
for(int j = i + 1, k = n; j <= n; j++, k--) {
sum += k * j;
mx = max(k * j, mx);
}
ans = max(ans, sum - mx);
}
cout << ans << endl;
}
打表的代码
void solve() {
int n;
cin >> n;
vector<int> a(n + 1);
vector<int> ans;
int an = 0;
for (int i = 1; i <= n; i++)a[i] = i;
do {
int res = 0;
int re = 0;
for (int i = 1; i <= n; i++)res += a[i] * i, re = max(re, a[i] * i);
if (an < res - re) {
an = res - re;
ans = a;
}
} while (next_permutation(a.begin() + 1, a.end()));
cout << n << ' ' << an << endl;
for (int i = 1; i <= n; i++)cout << ans[i] << ' ';
cout << endl;
}
2 2
2 1
3 7
1 3 2
4 17
1 2 4 3
5 35
1 2 5 4 3
6 62
1 2 3 6 5 4
7 100
1 2 3 4 7 6 5
8 152
1 2 3 4 8 7 6 5
9 219
1 2 3 4 5 9 8 7 6
10 303
1 2 3 4 5 6 10 9 8 7
11 406
1 2 3 4 5 6 7 11 10 9 8
标签:892,int,sum,cin,vp,vector,数组,ans,Div
From: https://www.cnblogs.com/north-h/p/17627064.html