概述
Polycarp and the Day of Pi
模拟
AC代码:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s = "#314159265358979323846264338327";
int T;
cin >> T;
while (T--) {
string t;
cin >> t;
int len = t.size();
t = '#' + t;
int ans = -1;
for (int i = 1; i <= len; i++) {
if (s[i] != t[i]) {
ans = i - 1;
break;
}
}
if (ans == -1) {
cout << len << 'n';
} else {
cout << ans << 'n';
}
}
return 0;
}
Taisia and Dice
贪心,计算需要在何时必须全部放最大的数和第二大的数(如果整除可能没有)即可,否则就放1
AC代码:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n, s, r;
cin >> n >> s >> r;
cout << s - r << " ";
int maxx = s - r;
s -= maxx;
for (int i = 0; i < n - 1; i++) {
int x = s / maxx, y = s % maxx;
int p = (y > 0 ? 1 : 0) + x;
if (p < n - 1 - i) {
cout << "1 ";
s--;
} else if (p == n - 1 - i) {
if (y > 0) {
cout << y << " ";
p--;
}
for (int j = 0; j < p; j++) {
cout << maxx << " ";
}
break;
}
}
cout << 'n';
}
return 0;
}
Premutation
根据题意可知,第一列最多的一定是第一个数,只有一个的一定是第二个数,有了这两个数后面的就迎刃而解,因为后面的数一定是一个用过的数和一个第一次出现的数,每次就放第一次出现的数即可
AC代码:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<vector<int>> a(n, vector<int> (n - 1));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
cin >> a[i][j];
}
}
vector<bool> vis(n + 1);
vector<int> ans;
for (int j = 0; j < n - 1; j++) {
int x = 0, y = 0, cnt1 = 0, cnt2 = 0;
for (int i = 0; i < n; i++) {
int u = a[i][j];
if (x == 0) {
x = u;
cnt1++;
continue;
} else if (x != u) {
y = u;
cnt2++;
continue;
}
if (x == u) {
cnt1++;
} else {
cnt2++;
}
}
if (x && y) {
if (cnt1 > cnt2) {
if (!vis[x]) {
ans.push_back(x);
vis[x] = true;
if (!vis[y]) {
ans.push_back(y);
vis[y] = true;
}
} else {
ans.push_back(y);
vis[y] = true;
}
} else if (cnt1 < cnt2) {
if (!vis[y]) {
ans.push_back(y);
vis[y] = true;
if (!vis[x]) {
ans.push_back(x);
vis[x] = true;
}
} else {
ans.push_back(x);
vis[x] = true;
}
} else {
if (!vis[x]) {
ans.push_back(x);
vis[x] = true;
if (!vis[y]) {
ans.push_back(y);
vis[y] = true;
}
} else {
ans.push_back(y);
vis[y] = true;
}
}
} else if (x) {
if (!vis[x]) {
ans.push_back(x);
vis[x] = true;
}
}
}
for (auto it : ans) {
cout << it << " ";
}
cout << 'n';
}
return 0;
}
Matryoshkas
根据题意,需要找每个区间的头,即如果是第一个数,那他一定是头,先排序,如果a[i]+1!=a[i+1],那么a[i+1]也一定是个头,找到了头以后,最少的区间个数也就是头有多少个,贪心地考虑这个区间肯定是越长越好,所以如果某个数的个数小于等于他前面数的个数,那么这个数和前面的数是在一个区间内的,如果大于前面数的个数,说明他还需要用多出来的部分自己当头来抵消掉多余的部分
AC代码:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<int> a(n);
map<int, int> mp;
for (int i = 0; i < n; i++) {
cin >> a[i];
mp[a[i]]++;
}
sort(a.begin(), a.end());
int len = unique(a.begin(), a.end()) - a.begin();
int ans = 0;
for (int i = 0; i < len; i++) {
if (i == 0) {
ans += mp[a[i]];
} else if (a[i - 1] + 1 != a[i]) {
ans += mp[a[i]];
} else {
ans += max(0, mp[a[i]] - mp[a[i - 1]]);
}
}
cout << ans << 'n';
}
return 0;
}
Vlad and a Pair of Numbers
根据运算法则可以看出,(a+b)=(a^b)+((a&b)<<1),因为异或是不进位加法,那么必然需要配合一个与运算来变成进位加法,有了这个公式可以发现,(a^b)=((a&b)<<1)=x,a+b=2*x,又因为((a&b)<<1)一定是个偶数,所以x为奇数的时候是不符合的,再考虑进位的过程,情况有四种,分别为00,01,10,11,首先00肯定对应的a和b的两位都是0,01和10因为不存在奇数,所以其实意义一样,那么考虑10,容易想到的是(11^01)=((11&01)<<1)=10,再考虑11,可知(11^00),(10^01)满足,但((11&00)<<1)=0,((10&01)<<1)=0,不满足,所以如果x的二进制中出现连续的1,则也是不符合的,之后只需要根据上述的构造,得到a和b,也就是找到所有两位为10的地方进行构造即可
AC代码:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int x;
cin >> x;
if (x & 1) {
cout << "-1n";
continue;
}
if (x & (x >> 1)) {
cout << "-1n";
continue;
}
LL a = 0, b = 0;
for (int i = 0; i < 31; i++) {
if ((((x >> i) & 1) == 0) && (((x >> (i + 1)) & 1) == 1)) {
a |= 1LL << i;
a |= 1LL << (i + 1);
b |= 1LL << i;
}
}
cout << a << " " << b << 'n';
}
return 0;
}
Timofey and Black-White Tree
根据题意,首先给出一个黑色的根,然后依次给出每次操作把哪个结点变成黑色,计算黑点与黑点之间的最小距离,首先考虑极端情况,一条链上以尽可能长的判断路径选择黑点,掐指一算感觉上如果从一个刚染黑的点暴力去dfs更新其他点距离黑色点的距离的话,耗时并不会太多
AC代码:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n, root;
cin >> n >> root;
vector<int> c(n - 1);
int ans = n;
for (int i = 0; i < n - 1; i++) {
cin >> c[i];
}
vector<vector<int>> G(n + 1);
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
vector<int> dist(n + 1, 0x3f3f3f3f);
function<void(int, int)> calc = [&](int u, int now) {
if (now >= ans || dist[u] <= now) {
return;
}
dist[u] = now;
for (auto v : G[u]) {
calc(v, now + 1);
}
};
calc(root, 0);
for (int i = 0; i < n - 1; i++) {
ans = min(ans, dist[c[i]]);
calc(c[i], 0);
cout << ans << " n"[i == n - 2];
}
}
return 0;
}
最后
以上就是甜美冬天为你收集整理的Codeforces Round #847 (Div. 3)(6/7)的全部内容,希望文章能够帮你解决Codeforces Round #847 (Div. 3)(6/7)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复