Codeforces Round #783 (Div. 2)
A. Direction Change
题意
从(1,1)点出发到(n,m),每次可以向上下左右四个方向移动,但是不能与上次移动方向相同
最少要移动多少不,如果不能到达输出 -1
思路
假设n<m
如图,先走到边界用 2*n 步,接下来如果离目标 1 格加1即可,如果离目标 2 格,则如下图
共需要走4步
代码
#include <bits/stdc++.h> using namespace std; const int maxm = 1e3 + 5; int n, m, a[maxm]; bool f[maxm][maxm]; int main() { int t; cin >> t; while (t--) { int a, b, x, y; cin >> x >> y; a = min(x, y), b = max(x, y); if (a == 1 && b > 2) { cout << -1 << endl; continue; } if (a == 1 && b == 2) { cout << 1 << endl; continue; } int ans = 0; ans = (a - 1) * 2; b = b - a; ans += (b / 2) * 4 + (b % 2); cout << ans << endl; } return 0; }
B. Social Distance
题意
有 m 把椅子摆成一个环,有 n 个人每个人有一个对应的值 ,表示其左右两边各有
个椅子不能坐人
问所有人是否都可以坐下
思路
我们首先可以让 最大的先坐,为了让空椅子利用率最大,把第二大和第三大的分别坐在其左右两边,以次类推每一个人相当于只占用了一边另一边包含在
比他大的上一个人中,一直加到最小和次小,此时最小的不用加,因为其两边包含在第二小和第三小中,因为最大的两边都用上因此要加两次
特判当 n>m 直接错误
代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxm = 1e3 + 5; int main() { int t; cin >> t; while (t--) { int a, b; cin >> a >> b; int mas = 0, mis = 1e9 + 7; int s[a]; for (int i = 0; i < a; i++) { cin >> s[i]; mas = max(mas, s[i]); mis = min(mis, s[i]); } if (a > b) { cout << "NO\n"; continue; } ll ans = mas + a - mis; for (int i = 0; i < a; i++) { ans += s[i]; if (ans > b) break; } if (ans > b) cout << "NO\n"; else cout << "YES\n"; } return 0; }
Make it Increasing
题意
给定一个序列 a ,b 为一个全零序列,每次操作可以使得 或
求使得 b b严格单调上升的最少的操作次数
思路
首先注意到,这些操作在同一个位置交替是没有意义的。因此考虑直接枚举某个位置不改变(0),其左侧全减,右侧全加。
代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll a[5005], mis = 1e18; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; for (int j = 1; j <= n; j++) { ll ans = 0, sum = 0; for (int i = j - 1; i >= 1; i--) { ans += a[i] - ans % a[i]; sum += ans / a[i]; } ans = 0; for (int i = j + 1; i <= n; i++) { ans += a[i] - ans % a[i]; sum += ans / a[i]; } mis = min(mis, sum); } cout << mis << "\n"; return 0; }