Codeforces Round 883 (Div. 3)
Codeforces Round 883 (Div. 3)
题目链接:Codeforces Round 883 (Div. 3)
A. Rudolph and Cut the Rope
思路
统计\(a_i\)大于\(b_i\)的点的数量就行。
代码
#include <bits/stdc++.h>
using namespace std;
void sol() {
int n, ans = 0;
cin >> n;
for (int i = 1; i <= n; ++i) {
int x, y;
cin >> x >> y;
if (y < x) ans += 1;
}
cout << ans << endl;
}
int main() {
int _;
cin >> _;
while (_--) sol();
return 0;
}
B. Rudolph and Tic-Tac-Toe
思路
判断'O'和'×'有没有连成三个就行,否则就是平局
代码
#include <bits/stdc++.h>
using namespace std;
char s[5][5];
void sol() {
for (int i = 1; i <= 3; ++i) cin >> (s[i] + 1);
int win = 0;
char wn;
for (int i = 1; i <= 3; ++i) {
if (s[i][1] == s[i][2] && s[i][2] == s[i][3]) {
if (s[i][1] == '.') continue;
win = 1;
wn = s[i][1];
}
}
if (win == 1) {
cout << wn << endl;
return;
}
for (int i = 1; i <= 3; ++i) {
if (s[1][i] == s[2][i] && s[2][i] == s[3][i]) {
if (s[1][i] == '.') continue;
win = 1;
wn = s[1][i];
}
}
if (win == 1) {
cout << wn << endl;
return;
}
if ((s[1][1] == s[2][2] && s[2][2] == s[3][3]) ||
(s[3][1] == s[2][2] && s[2][2] == s[1][3])) {
if (s[2][2] != '.') {
win = 1;
wn = s[2][2];
}
}
if (win == 1) {
cout << wn << endl;
return;
}
cout << "DRAW" << endl;
}
int main() {
int _;
cin >> _;
while (_--) sol();
return 0;
}
C. Rudolf and the Another Competition
思路
对于每个题目,不难看出,最优策略是先写简单题。
会爆int,需要开LL。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
#define LL long long
int a[maxn];
struct poi {
LL sum;
int t;
bool operator<(const poi b) const {
return t > b.t || (t == b.t && sum < b.sum);
}
};
set<poi> s;
map<poi, vector<int>> p;
void sol() {
s.clear();
p.clear();
int n, m, k;
cin >> n >> m >> k;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) cin >> a[j];
sort(a + 1, a + m + 1);
int sum = 0, t = 0;
LL summ = 0;
for (int j = 1; j <= m && sum + a[j] <= k; ++j) {
sum += a[j];
summ += sum;
t += 1;
}
p[poi{summ, t}].push_back(i);
s.insert(poi{summ, t});
}
int idx = 0;
for (auto x : s) {
for (auto xx : p[x]) {
if (xx == 1) {
cout << idx + 1 << endl;
return;
}
}
int i = p[x].size();
idx += i;
}
}
int main() {
int _;
cin >> _;
while (_--) sol();
return 0;
}
D. Rudolph and Christmas Tree
思路
简单数学计算面积题,一点弯都没绕,还以为他会卡double精度,但是也没卡
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
#define LL long long
int a[maxn];
void sol() {
int n, d, h;
cin >> n >> d >> h;
for (int i = 1; i <= n; ++i) cin >> a[i];
sort(a + 1, a + n + 1);
a[n + 1] = a[n] + h + 1;
double ans = 0;
for (int i = 1; i <= n; ++i) {
if (a[i] + h <= a[i + 1]) {
ans += 0.5 * d * h;
}
else {
double tmp = 1.0 * d * (1.0 * (a[i] + h - a[i + 1]) / h);
ans += 0.5 * d * h - 0.5 * tmp * (a[i] + h - a[i + 1]);
}
}
printf("%.7lf\n", ans);
}
int main() {
int _;
cin >> _;
while (_--) sol();
return 0;
}
E. Rudolf and Snowflakes
思路
这个题实际上是让判断n是否能写成\(1+x+x^2+...+x^k=n\)的形式。
简单版本可以遍历\(x\),再遍历每个\(k\)就行。
由于困难版本\(1≤n≤1e18\),所以不能直接遍历\(x\)。考虑到两种情况:\(1≤x<1e6\)时,\(x\)可代入\(k≥3\)时的式子,但当\(x\)再大的话代入\(k≥3\)时的式子的之后,产生的n就会比\(1e18\)大,此时只能通过\(1+x+x^2=n\)来产生合法的n。从而对于\(k≥3\),遍历\(x\)从\(1\)到\(1e6\),产生所有可能的\(n\);对于\(k<3\),二分\(x\)从\(2\)到\(1e9\)来判断\(n\)能不能被生成。
代码
#include <bits/stdc++.h>
using namespace std;
#define LL long long
map<LL, bool> vis;
LL bs(LL l, LL r, LL x) {
if (l == r) return l;
LL mid = (l + r) / 2;
if (mid * mid + mid + 1 < x)
return bs(mid + 1, r, x);
else
return bs(l, mid, x);
}
void sol() {
LL n;
cin >> n;
if (vis[n]) {
cout << "YES" << endl;
return;
}
LL x = bs(2, 1000000000, n);
if (x * x + x + 1 != n) {
cout << "NO" << endl;
} else {
cout << "YES" << endl;
}
}
int main() {
LL n = 1e6, nn = 1e18;
for (LL i = 2; i <= n; i++) {
LL sum = i + 1 + i * i, tmp = i * i * i;
while (sum + tmp <= nn) {
sum += tmp;
vis[sum] = true;
if ((nn - sum) / tmp < i) break;
tmp *= i;
}
}
int _;
cin >> _;
while (_--) sol();
return 0;
}
F. Rudolph and Mimic
没意思,直接下一题。。
G. Rudolf and CodeVid-23
思路
由于\(1\leq n\leq 10\),所以所有健康状态的数量最大为1024,将每个健康状态看成点,边数最多为\(1e6\)水平,其实就是让求最短路,dijkstra一下就行。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1030;
struct edge {
int to, w;
bool operator<(const edge b) const {
return to < b.to || (to == b.to && w < b.w);
}
};
struct node {
int idx, dis;
bool operator<(const node b) const {
return dis > b.dis || (dis == b.dis && idx > b.idx);
}
};
set<edge> edges[maxn];
int dijkstra(int x, int n) {
vector<int> dis(n, INT_MAX);
vector<bool> vis(n, false);
priority_queue<node> q;
q.push(node{x, 0});
dis[x] = 0;
while (!q.empty()) {
node now = q.top();
q.pop();
if (vis[now.idx]) continue;
vis[now.idx] = true;
for (auto x : edges[now.idx]) {
if (dis[x.to] > x.w + now.dis) {
dis[x.to] = x.w + now.dis;
q.push(node{x.to, dis[x.to]});
}
}
}
if (dis[0] == INT_MAX)
return -1;
else
return dis[0];
}
void sol() {
int n, m;
cin >> n >> m;
for (int i = 0; i < 1 << n; ++i) edges[i].clear();
bitset<10> s;
cin >> s;
int x = (int)s.to_ulong();
for (int i = 1; i <= m; ++i) {
int w, l, r;
cin >> w >> s;
l = (int)s.to_ulong();
cin >> s;
r = (int)s.to_ulong();
for (int j = 0; j < 1 << n; ++j)
edges[j].insert(edge{(j & (j ^ l)) | r, w});
}
cout << dijkstra(x, 1 << n) << endl;
}
int main() {
int _;
cin >> _;
while (_--) sol();
return 0;
}