AtCoder Beginner Contest 265 A-F
AtCoder Beginner Contest 265 A-F
https://atcoder.jp/contests/abc265
A - Apple
有两种购买策略: 元买一个苹果 or 元买三个苹果,问买 个苹果最少要花多少钱
#include <bits/stdc++.h>
using namespace std;
int main () {
int x, y, n;
cin >> x >> y >> n;
if (n < 3 || x * 3 <= y) {
cout << x * n << endl;
}
else {
cout << (n/3)*y + (n%3)*x;
}
}
B - Explore
从 走到 点需要消耗 , 有 个点 存在补助,初始有 , 问能不能从 走到
注意先减再添加补助
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5;
int n, m, t;
int a[N], b[N];
signed main () {
cin >> n >> m >> t;
for (int i = 2; i <= n; i++) cin >> a[i];
for (int i = 1; i <= m; i++) {
int x, y;
cin >> x >> y;
b[x] = y;
}
for (int i = 2; i <= n; i++) {
t -= a[i];
if (t <= 0) {
cout << "No\n";
return 0;
}
t += b[i];
}
cout << "Yes\n";
}
//模拟
C - Belt Conveyor
有 的地图,初始在 , 规则: 向上一格, 向下一格, 向右一格, 向左一格。
问走到哪里时下一步就出界,永不出界输出
按题意模拟,如果走完了整个地图还不出界,则永不出界。
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
int n, m;
char a[N][N];
bool check (int x, int y) {
if (x > n || x <= 0 || y > m || y <= 0)
return false;
return true;
}
signed main () {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
int x = 1, y = 1, sx, sy;
int cnt = n * m;
while (1) {
cnt --;
sx = x, sy = y;
if (a[x][y] == 'U') x --;
else if (a[x][y] == 'D') x ++;
else if (a[x][y] == 'R') y ++;
else if (a[x][y] == 'L') y --;
if (!check (x, y)) {
cout << sx << ' ' << sy;
break;
}
if (cnt <= 0) {
cout << -1;
break;
}
//x = sx, y = sy;
}
}
//一直走走到出界
D - Iroha and Haiku (New ABC Edition)
现有一数列 , 问能不能找到四点 , 满足:
暴力 查找
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5;
int n, p, q, r;
int sum[N];
signed main () {
cin >> n >> p >> q >> r;
set<int> s;
s.insert (0);
for (int i = 1; i <= n; i++) {
int x; cin >> x;
sum[i] = sum[i-1] + x;
s.insert (sum[i]);
}
for (int i = 1; i <= n; i++) {
if (s.count (sum[i-1]+p) && s.count (sum[i-1]+p+q) && s.count (sum[i-1]+p+q+r)) {
cout << "Yes\n";
return 0;
}
}
cout << "No\n";
}
//sum[y-1]-sum[x-1]=p
//sum[z-1]-sum[y-1]=q
//sum[w-1]-sum[z-1]=r
E - Warp
假设现在在 , 下一步可以选择走到 or or , 且有 个障碍, 问走 步能有多少种可能的路径
定义状态 表示 1走了 次,2走了 次,3走了 次。
线性 dp 路径转移即可
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> pii;
const int N = 305, mod = 998244353;
int A, B, C, D, E, F, n, m;
int f[N][N][N]; //1走了i次,2走了j次,3走了k次
signed main () {
cin >> n >> m >> A >> B >> C >> D >> E >> F;
set<pii> s;
for (int i = 1; i <= m; i++) {
int x, y;
cin >> x >> y;
s.insert({x, y});
}
f[0][0][0] = 1;
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n - i; j++)
for (int k = 0; k <= n - i - j; k++) {
int x = i*A + j*C + k*E, y = i*B + j*D + k*F;
if (!i && !j && !k) continue;
if (s.count ({x, y})) continue;
if (i) f[i][j][k] += f[i-1][j][k];
if (j) f[i][j][k] += f[i][j-1][k];
if (k) f[i][j][k] += f[i][j][k-1];
f[i][j][k] %= mod;
}
int ans = 0;
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n - i; j++) {
ans += f[i][j][n-i-j], ans %= mod;
}
cout << ans;
}
//移动n次
F - Manhattan Cafe
题意:有两点 , 各有 个维度,问有多少个点满足到 和 的曼哈顿距离均
分析:可以把这样的点分为两类————在 之间的,在 外的。
对于在两点之外的 , 每走一格, 都会同时 ;
对于在两点之间的 , 则是 定值,即 。
由这两种特殊性质得,可以维护矩阵的主对角线和副对角线的前缀和,即可dp 转移
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1005, M = 105, mod = 998244353;
int p[M], q[M], dp[N][N], C[N][N], E[N][N];
int n, d;
signed main() {
cin >> n >> d;
for (int i = 0; i < n; i++) cin >> p[i];
for (int i = 0; i < n; i++) cin >> q[i];
dp[0][0] = 1;
for (int k = 0; k < n; k++) {
int z = abs(p[k] - q[k]);
for (int i = 0; i <= d; i++)
for (int j = 0; j <= d; j++) {
C[i+1][j+1] = (C[i][j] + dp[i][j]) % mod; //主对角线
E[i+1][j] = (E[i][j+1] + dp[i][j]) % mod; //副对角线
dp[i][j] = (C[i][max(j-z, 0ll)] + C[max(i-z, 0ll)][j]) % mod;
int m = max(z - j, 0ll);
if (i >= m) dp[i][j] = (dp[i][j] + E[i+1-m][j-z+m]) % mod;
if (i >= z) dp[i][j] = (dp[i][j] - E[i-z][j+1] + mod) % mod;
}
}
int ans = 0;
for (int i = 0; i <= d; i++)
for (int j = 0; j <= d; j++)
ans = (ans + dp[i][j]) % mod;
cout << ans;
}