「赛后总结」 AtCoder Beginner Contest 174
题意/题解
A.Air Conditioner
题意:
判断输入的整数是否不小于 30
题解:
签到题。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
int a;
int main() {
std::cin >> a;
if (a >= 30) puts("Yes");
else puts("No");
return 0;
}
B.Distance
题意:
一边输入一边算距离然后判断
题解:
签到题。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
int n, d;
int main() {
scanf("%d %d", &n, &d); int ans = 0;
for (int i = 1, x, y; i <= n; ++i) {
scanf("%d %d", &x, &y);
double dis = sqrt(1ll * x * x + 1ll * y * y);
if (dis <= d) ++ans;
}
printf("%d\n", ans);
return 0;
}
C.Repsept
题意:
给你一个 \(k\) 从他的倍数中找到第一个每一位都是 \(7\) 的输出这个倍数的长度。
题解:
枚举倍数有点难搞,于是枚举每一位都是 \(7\) 的数。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 10000001
int n, now;
bool flag;
int main() {
scanf("%d", &n);
for (int i = 1; i < M; ++i) {
now = (1ll * now * 10 % n + 7) % n;
if (now == 0) {
printf("%d\n", i);
flag = true; break;
}
}
if (!flag) puts("-1");
return 0;
}
D.Alter Altar
题意:
\(n\) 个石子排成一行,石子分两种,一种为R
一种为W
,可以进行两种操作:交换任意两个石子或改变一个的类型。问最少几次操作后不存在R
石子紧邻的左边为W
的情况
题解:
最后一定是 RRRRR..WWWWWW...
的样子。
答案就是总的 R
的个数减去前 R
的个数个石子中 R
的个数。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 200001
std::string s;
int n, sw[M], sr[M];
int main() {
scanf("%d", &n);
std::cin >> s;
if (s[0] == 'W') sw[0] = 1;
if (s[0] == 'R') sr[0] = 1;
for (int i = 1; i < n; ++i) {
sw[i] = sw[i - 1], sr[i] = sr[i - 1];
if (s[i] == 'W') ++sw[i];
else ++sr[i];
}
std::cout << sr[n - 1] - sr[sr[n - 1] - 1] << '\n';
return 0;
}
E Logs
题意:
有 \(n\) 个木头,每个木头有一个自己的长度,你可以切 \(k\) 次,使得切出来的木头中最长的最短,问最短为多长(小数在切完 \(k\) 次后四舍五入)。
题解:
二分答案。
代码来自Ta_gee.
#include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < n; i++)
using namespace std;
using Graph = vector<vector<int>>;
using ll = long long;
using P = pair<int, int>;
const int INF = 10001000;
ll k;
bool f(int x, vector<int> &a) {
ll sum = 0;
for (int t : a) {
sum += (t-1)/x;
}
return sum <= k;
}
int main() {
ll n;
cin >> n >> k;
vector<int> a(n);
rep(i,n) cin >> a[i];
// int x;
// cin >> x;
// if (f(x, a)) {cout << "Yes" << endl;}
// else cout << "No" << endl;
ll right, left;
right = 1000000000;
left = 0;
while (right - left > 1) {
ll mid = (left + right)/2;
if (f(mid, a)) {
right = mid;
}
else {
left = mid;
}
}
cout << right << endl;
return 0;
}
F Range Set Query
题意:
一个长为 \(n\) 的序列,每次询问一个区间 \([L,R]\) 中有不同的数有几种
题解:
莫队板子。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define MAXN 500001
int n, m, a[MAXN], ans[MAXN];
int sqrn, num[MAXN], ba[MAXN];
struct query {
int x, y, id;
friend bool operator < (query q1, query q2) {
if (num[q1.x] == num[q2.x]) return num[q1.y] < num[q2.y];
return num[q1.x] < num[q2.x];
}
}q[MAXN];
int main() {
scanf("%d %d", &n, &m), sqrn = sqrt(n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
num[i] = (i - 1) / sqrn + 1;
}
for (int i = 1; i <= m; ++i) {
scanf("%d %d", &q[i].x, &q[i].y);
q[i].id = i;
}
std::sort(q + 1, q + m +1);
int l = 1, r = 1, now = 1;
ba[a[l]] = 1;
for (int i = 1; i <= m; ++i) {
while(l > q[i].x) {
++ba[a[--l]];
if (ba[a[l]] == 1) ++now;
}
while(r < q[i].y) {
++ba[a[++r]];
if (ba[a[r]] == 1) ++now;
}
while(l < q[i].x) {
if (ba[a[l]] == 1) --now;
--ba[a[l++]];
}
while(r > q[i].y) {
if (ba[a[r]] == 1) --now;
--ba[a[r--]];
}
ans[q[i].id] = now;
}
for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
return 0;
}
rating & 总结
-
太菜了。
-
做不出 C、D 是没想到的。
-
做出了 F 更没想到。
-
由没做出 C、D 但是做出了 F 可得需要多锻炼下思维。。。