Codeforces Round #696 (Div. 2)
A. Puzzle From the Future
题意:给出一个二进制数b,要求另一个二进制数a使a + b再经过一定操作后的结果最大
(操作:结果中相邻单位的数字相同要合并为一个数);
思路:一道贪心题,首先明确位数多的始终比位数少的要大,a和b相加时能加1就加1,否则就加上0;
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn], b[maxn], c[maxn];
int main() {
int t; scanf("%d", &t);
while(t--) {
int len; scanf("%d", &len);
for(int i = 0; i < len; i++) scanf("%1d", &b[i]);
a[0] = 1; c[0] = a[0] + b[0];
for(int i = 1; i < len; i++) {
if(1 + b[i] == c[i - 1]) a[i] = 0;
else a[i] = 1;
c[i] = a[i] + b[i];
}
for(int i = 0; i < len; i++)
printf("%d", a[i]);
puts("");
}
return 0;
}
B. Different Divisors
题意: 求出a, 要求a至少有4个因子且a的任意两个因子的差不小于d
思路:这种不太复杂的找规律题,直接打表观察
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100000;
int prime[maxn], visit[maxn];
//欧拉筛法
void Prime() {
for(int i = 2; i <= maxn; i++) {
if(!visit[i]) prime[++prime[0]] = i;
for(int j = 1; j <= prime[0] && prime[j] * i <= maxn; j++) {
visit[prime[j] * i] = 1;
if(i % prime[j] == 0) break;
}
}
}
int main() {
Prime();
int t; scanf("%d", &t);
while(t--) {
int d; scanf("%d", &d);
int p = lower_bound(prime + 1, prime + prime[0] + 1, d + 1) - prime;
p = prime[p];
int q = lower_bound(prime + 1, prime + prime[0] + 1, p + d) - prime;
q = prime[q];
cout << p * q << endl;
}
return 0;
}
C. Array Destruction
题意:要删除一个数组所有的数,要求一次只能删除两个数,且两个数之和必须为上一次删除的两数中的最大值。
思路:因为这一次删除的数中的最大值为下一次两数的和,则必须要求删除的数中要包含当前数组中的最大值,否则该最大值将无法被删除。现在问题就是第一次删除时除最大数外的另外一个数如何选择,注意到n最大为1000,O(n^2)也是可以过的,枚举每一种情况就行了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2 * 1000 + 10;
typedef pair<int, int> P;
void solve() {
int arr[maxn];
int n, mx = 0, pos;
scanf("%d", &n);
n *= 2;
for(int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
if(arr[i] > mx) { mx = arr[i], pos = mx; }
}
for(int i = 0; i < n; i++) { //枚举每种初始的x;
if(i == pos) continue;
vector<P> res;
multiset<int> ms;
for(int i = 0; i < n; i++) ms.insert(arr[i]);
int x = mx + arr[i], flag = 1;
while(!ms.empty()) {
int t = *ms.rbegin();
ms.erase(ms.find(t)); //一定要先删除,否则当t == x - t 且 t 只出现一次时会出现问题;
if(ms.find(x - t) == ms.end()) {
flag = 0;
break;
}
else {
ms.erase(ms.find(x - t));
res.emplace_back(t, x - t);
x = t;
}
}
if(flag) {
printf("YES\n%d\n", res[0].first + res[0].second);
for(auto t : res) {
printf("%d %d\n", t.first, t.second);
}
return ;
}
}
printf("NO\n");
}
int main() {
int t; scanf("%d", &t);
while(t--) {
solve();
}
return 0;
}
小总结:
1.emplace_back 和 push_back 有相同的作用,但前者效率要高很多。
2.mutiset就是可以有重复元素的set。
其它的待补