且歌且行,眉目轻盈。何妨吟啸且徐行。|

胖柚の工作室

园龄:2年1个月粉丝:2关注:15

Atcoder Beginner Contest 354

A - Exponential Plant

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int N;
cin >> N;
int ans = 0;
int cnt = 0;
while (ans <= N) {
ans += 1 << cnt;
cnt++;
}
cout << cnt << "\n";
return 0;
}

B - AtCoder Janken 2

本来想开 vector<pair<string,int>> 的,但发现其实没有必要,整数部分只需求和即可。另外,多个字符串按字典序升序排序可以直接存 vectorsort

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr);
int N, ans = 0;
cin >> N;
vector<string> s(N);
for (int i = 0; i < N; i++) {
cin >> s[i];
int c;
cin >> c;
ans += c;
}
ans %= N;
sort(s.begin(), s.end());
cout << s[ans] << "\n";
return 0;
}

C - AtCoder Magics

暴力思路:将牌按 a 值从小到大排序,对当前每张牌 i,看其后面是否有牌比其 c 值小,有的话就把当前 iorder 置为 0
时间复杂度为 O(n2),显然会 TLE。

image

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int N = 2e5 + 10;
struct point {
int a, c, order;
}p[N];
bool cmp(const point& x, const point& y) {
return x.a < y.a;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr);
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> p[i].a >> p[i].c;
p[i].order = i + 1;
}
sort(p, p + n, cmp);
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (p[i].c > p[j].c) {
p[i].order = 0;
break;
}
}
}
int ans = 0;
vector<int> t;
for (int i = 0; i < n; i++) {
if (p[i].order) {
ans++;
t.push_back(p[i].order);
}
}
cout << ans << "\n";
sort(t.begin(), t.end());
for (auto i : t) cout << i << " ";
return 0;
}

优化:由于是对当前每张牌 i 考虑后面是否有牌的 c 值小于当前 c 值,因此只需维护后缀最小值即可。从后往前维护一个 c 的最小值,若当前 c 值小于最小值就更新最小值,否则将当前的 order 置为 0

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int N = 2e5 + 10;
struct point {
int a, c, order;
}p[N];
bool cmp(const point& x, const point& y) {
return x.a < y.a;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr);
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> p[i].a >> p[i].c;
p[i].order = i + 1;
}
sort(p, p + n, cmp);
int minn = p[n - 1].c;
for (int i = n - 1; i >= 0; i--) {
if (p[i].c > minn) {
p[i].order = 0;
} else {
minn = p[i].c;
}
}
int ans = 0;
vector<int> t;
for (int i = 0; i < n; i++) {
if (p[i].order) {
ans++;
t.push_back(p[i].order);
}
}
cout << ans << "\n";
sort(t.begin(), t.end());
for (auto i : t) cout << i << " ";
return 0;
}

更简洁的写法:jiangly

#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int N;
std::cin >> N;
std::vector<int> A(N), C(N);
for (int i = 0; i < N; i++) {
std::cin >> A[i] >> C[i];
}
std::vector<int> p(N);
std::iota(p.begin(), p.end(), 0);
std::sort(p.begin(), p.end(),
[&](int i, int j) {
return A[i] > A[j];
});
int min = 1E9 + 1;
std::vector<int> ans;
for (auto i : p) {
if (C[i] < min) {
min = C[i];
ans.push_back(i + 1);
}
}
std::sort(ans.begin(), ans.end());
std::cout << ans.size() << "\n";
for (int i = 0; i < ans.size(); i++) {
std::cout << ans[i] << " \n"[i == ans.size() - 1];
}
return 0;
}

D - AtCoder Wallpaper

经过观察可发现整个图形是由无数个
image
构成的,对于该基本图形用数组表示其每个单元面积的二倍,然后循环看以 (n,m) 为右上顶点,坐标原点为左下顶点的矩形中有多少个该基本图形。

横向的循环节为 4,纵向的循环节为 2,通过找规律不难得出计算表达式。

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
constexpr int v[4][2] = {{2, 1}, {1, 2}, {0, 1}, {1, 0}};
i64 solve(int n, int m) {
i64 ans = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 2; j++) {
ans += 1LL * v[i][j] * ((n - i + 3) >> 2) * ((m - j + 1) >> 1);
}
}
return ans;
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int A, B, C, D;
cin >> A >> B >> C >> D;
i64 ans = solve(C, D) - solve(C, B) - solve(A, D) + solve(A, B);
cout << ans;
return 0;
}

本文作者:胖柚の工作室

本文链接:https://www.cnblogs.com/pangyou3s/p/18224286

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   胖柚の工作室  阅读(18)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起