找到相加规则。先对数组按照从小打到排序,第一次,先让第一个数和第二个数大小相等,即相加的n-1个数只除了第二个数字,第二次,让第一第二个数和第三个数大小相等,即相加的n-1个数只除了第三个数字,之后每次相加同理,相加n-1次,即可得到答案,最后的结果就是最大的数字加上每次两个数字的差值,做一个前缀和相加。
#include<bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while(t--) {
int n;
cin >> n;
vector<int> p(n, 0);
for(int i = 0; i < n; i++)
cin >> p[i];
sort(p.begin(), p.end());
int res = 0;
for(int i = 1; i < n; i++) {
p[i] += res;
int tmp = p[i] - p[i - 1];
res = res + tmp;
}
cout << res << " " << p[n - 1] << endl;
}
return 0;
}
这道题借用了题解中的解题思路。这里参考一下,
一开始的想法是从前往后相加相同的数字,然后删除,但是会导致之后的数字也相同,导致并不是最少的次数。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
map<int, int> p;
for(int i = 0; i < n; i++) {
int a;
cin >> a;
p[a] += 1;
}
int res = 0;
for(map<int,int>::iterator iter = p.begin(); iter != p.end(); iter++)
res = res + iter->second - 1;
cout << res << endl;
return 0;
}
简单模拟输出,一眼可知,凳子消除最贵的商品,所以比较凳子和购物车两者的最小值,即可以得到最终的结果。
#include <bits/stdc++.h>
using namespace std;
struct node {
double value;
int desk;
};
bool cmp(const struct node& a, const struct node& b) {
return a.value < b.value;
}
int main() {
int t;
cin >> t;
while(t--) {
int n, m;
cin >> n >> m;
vector<node> p;
int desknum = 0;
for(int i = 0; i < n; i++) {
struct node k;
cin >> k.value >> k.desk;
p.emplace_back(k);
if(k.desk == 1)
desknum += 1;
}
sort(p.begin(), p.end(), cmp);
double res = 0.0;
int idx = n - 1;
for(int i = 0; i < min(desknum, m); i++)
res = res + p[idx--].value / 2.0;
while(idx >= 0)
res = res + p[idx--].value;
printf("%.1lf\n", res);
}
return 0;
}
从小到大排序,然后选择区间最小最大差值为k以下的,包含最多数的区间即可。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<int> p(n, 0);
for(int i = 0; i < n; i++)
cin >> p[i];
sort(p.begin(), p.end());
int res = 0;
for(int i = 1; i < n; i++) {
int pre = i;
while(abs(p[i] - p[i - 1]) <= m && i < n)
i += 1;
if(pre == i)
res += 1;
else
i -= 1;
}
cout << res + 1 << endl;
return 0;
}
我记得,这是一道,2019年CCPC江西省赛的赛题,签到题。结果就是数组最大值的两倍,因为包含上山和下山。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> p(n, 0);
int res = 0;
for(int i = 0; i < n; i++) {
cin >> p[i];
res = max(res, p[i]);
}
cout << res * 2 << endl;
return 0;
}
最大最小值相减即可得到答案
同样是求区间最小最大差值为k,包含最多的数,之前有相同题目。
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while(t--) {
int n, k;
cin >> n >> k;
vector<int> p(n, 0);
for(int i = 0; i < n; i++)
cin >> p[i];
sort(p.begin(), p.end());
int res = 0;
for(int i = 0; i < n; i++) {
int idx = lower_bound(p.begin(), p.end(), p[i] + k) - p.begin();
int sum = idx - i;
if(p[idx] - p[i] == k)
sum += 1;
res = max(res, sum);
}
cout << res << endl;
}
return 0;
}
每次合并两个最大值即可。即排序数组的最后两个数字。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> p;
for(int i = 0; i < n; i++) {
int a;
cin >> a;
p.emplace_back(a);
}
sort(p.begin(), p.end());
int res = 0;
for(int i = n - 1; i >= 1; i--) {
int a = p[p.size() - 1];
p.pop_back();
int b = p[p.size() - 1];
p.pop_back();
res = res + a * b;
p.emplace_back(a + b);
}
cout << res << endl;
return 0;
}