(6/6) AtCoder Beginner Contest 186
A - Brick
题意:
有一个车最多可以装N斤,一块砖M斤,问最多可以装多少砖。
思路:
N/M下取整。
代码:
#include <bits/stdc++.h>
using namespace std;
void work() {
int a, b;
cin >> a >> b;
cout << a / b << endl;
}
int32_t main() {
int cas;
cas = 1;
while (cas--) work();
}
B - Blocks on Grid
题意:
给你一个int数组,每个数组元素都可以减去若干值,问最少减去多少值可以使数组元素全部相等。
思路:
找到最小元素,让每个元素都等于最小元素。
代码:
#include <bits/stdc++.h>
using namespace std;
int a[101][101];
int mn = 101;
int res;
void work() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
mn = min(a[i][j], mn);
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
res += a[i][j] - mn;
}
cout << res << endl;
}
int32_t main() {
int cas;
cas = 1;
while (cas--) work();
}
C - Unlucky 7
题意:
给你一个数N,问1到N中有多少个数的十进制和八进制的每一位都不含7。
思路:
枚举1到N,把每个数转为十进制和八进制检查统计。
代码:
#include <bits/stdc++.h>
using namespace std;
int res;
bool judge(int x) {
vector<int> v;
while (x) {
v.push_back(x % 8);
x /= 8;
}
for (int i = 0; i < v.size(); i++) {
if (v[i] == 7) return 0;
}
return 1;
}
void work() {
int n;
cin >> n;
int res = 0;
for (int i = 1; i <= n; i++) {
if (!judge(i)) continue;
int x = i;
int f = 0;
while (x) {
if (x % 10 == 7) f = 1;
x /= 10;
}
if (f) continue;
res++;
}
cout << res << endl;
}
int32_t main() {
int cas;
cas = 1;
while (cas--) work();
}
D - Sum of difference
题意:
给你N个数,有正有负。
问每两对的差的绝对值之和为多少,不重复,即i和j与j和i算一对。
思路:
从小到大排序,第一个数被减去n-1次,第二个数被减去n-3次,以此类推。
正-负=正,符合要求。
负-负=正,符合要求。
正-正=正,符合要求。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[200010];
void work() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + n + 1);
int res = 0;
int k = -(n-1);
for (int i = 1; i <= n; i++) {
res += k * a[i];
k += 2;
}
cout << res << endl;
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(0);
int cas;
cas = 1;
while (cas--) work();
}
E - Throne
题意:
N个椅子围成全,每次可以顺势针走K个,出发点在顺时针离目标点S个位置上,求最少走几次。
思路:
x
K
≡
(
N
−
S
)
m
o
d
N
xK \equiv (N-S) \mod N
xK≡(N−S)modN 求最小的正整数x。
套线性同余方程的板子。
代码:
#include <algorithm>
#include <iostream>
#define int long long
using namespace std;
typedef long long LL;
int exgcd(int a, int b, int &x, int &y) {
if (!b) {
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int32_t main() {
int t;
cin >> t;
while (t--) {
int n, s, k;
cin >> n >> s >> k;
s = n - s;
int x, y;
int d = exgcd(k, n, x, y);
if (s % d) puts("-1");
else cout << ((int)(s / d * x) % (n / d) + n / d) % (n / d) << endl;
}
return 0;
}
F - Rook on Grid
题意:
给一个N*M的矩阵,N,M为2e5的数据。
矩阵中有K个障碍物,问从1,1的位置出发,两步可以到达的所有位置的个数。
思路:
我们假设黑色的格子是障碍物,红色的格子是不能到达的点。
那么当一个点不能到达时,它左侧同行必有一个格子为障碍物,它上侧同列必有一个障碍物。
如果障碍物在第一列或者第一行出现,那么这一列或这一行的后面都无法到达,都假设存在障碍物,我们增加障碍物的个数,但是记得去重。
我们假设灰色为增加的障碍物。
因此障碍物个数要开3*N大小的数组。
所有我们枚举每一个障碍物,标记每个障碍物出现的列。
那么存在障碍物的每一行中不能到达的点的个数为,从这一行第一个障碍物开始到这一行末尾的每一列标记列数之和,单点修改,区间查询,可以考虑树状数组实现。
代码:
#include <bits/stdc++.h>
#define int long long
#define lowbit(x) x & (-x)
using namespace std;
constexpr int maxn = 600010;
int tr[maxn];
bool vis[maxn];
struct Point {
int x, y;
bool operator < (const Point &W) const {
if (x == W.x) return y < W.y;
else return x < W.x;
}
bool operator == (const Point &W) const {
return x == W.x && y == W.y;
}
} p[maxn];
void add(int x, int n) {
for (int i = x; i <= n; i += lowbit(i)) tr[i]++;
}
int query(int x) {
int ans = 0;
for (int i = x; i > 0; i -= lowbit(i)) ans += tr[i];
return ans;
}
void work() {
int H, W, M;
cin >> H >> W >> M;
int x_min = maxn, y_min = maxn;
for (int i = 1; i <= M; i++) {
cin >> p[i].x >> p[i].y;
if (p[i].x == 1) x_min = min(x_min, p[i].y);
if (p[i].y == 1) y_min = min(y_min, p[i].x);
}
// cout << M << endl;
for (int i = x_min + 1; i <= W; i++) p[++M] = {1, i};
for (int i = y_min + 1; i <= H; i++) p[++M] = {i, 1};
sort(p + 1, p + 1 + M);
M = unique(p + 1, p + M + 1) - (p + 1);
// for (int i = 1; i <= M; i++) cout << p[i].x << " " << p[i].y << endl;
int tmp = 0, h = 1;
for (int i = 1; i <= M; i++) {
if (!vis[p[i].y]) {
vis[p[i].y] = 1;
add(p[i].y, W);
// cout << "---" << endl;
}
if (i == M || p[i].x != p[i + 1].x) {
tmp += query(W) - query(p[h].y - 1);
h = i + 1;
}
}
cout << 1ll * H * W - tmp << endl;
}
int32_t main() {
work();
}