A. Direction Change
题意:给定一个 n ∗ m n * m n∗m 的方格图,在不能连续朝同一个方向走的前提下,问从 ( 1 , 1 ) (1, 1) (1,1) 走到 ( n , m ) (n, m) (n,m) 的最少步数为多少
做法:先右下右下的走,走到右边界或者下边界,步数为 ( m i n ( n , m ) − 1 ) ∗ 2 (min(n, m) - 1) * 2 (min(n,m)−1)∗2 ,再往右或往下走,步数为 ( m a x ( n , m ) − m i n ( n , m ) ) / 2 ∗ 2 + ( m a x ( n , m ) − m i n ( n , m ) ) (max(n, m) - min(n, m)) / 2 * 2 + (max(n, m) - min(n, m)) % 2 (max(n,m)−min(n,m))/2∗2+(max(n,m)−min(n,m)) ,相加即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
if (n == 1 && m == 1) cout << 0 << '\n';
else if (n == 1 && m > 2 || m == 1 && n > 2) cout << -1 << '\n';
else
{
if (n > m) swap(n, m);
cout << 2 * (n - 1) + ((m - n) / 2) * 4 + (m - n) % 2 << '\n';
}
}
return 0;
}
B. Social Distance
题意:给定围成圈的 m m m 个座位,有 n n n 个人入座,每个人的座位两边都需要空出来 a [ i ] a[i] a[i] 个座位,问能否满足
做法:从大到小排序,贪心判断是否满足即可
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
sort(a.begin(), a.end());
reverse(a.begin(), a.end());
int cnt = 2 * a.front();
for (int i = 1; i < n - 1; i++) cnt += a[i];
if (cnt <= m - n) cout << "YES" << '\n';
else cout << "NO" << '\n';
}
return 0;
}
C. Make it Increasing
题意:给定一个序列 a a a 和一个全为 0 0 0 的序列 b b b ,你可以让 b [ i ] + = a [ i ] b[i] += a[i] b[i]+=a[i] 或 b [ i ] − = a [ i ] b[i] -= a[i] b[i]−=a[i] ,问让 b b b 为升序的最少操作次数为多少
做法:暴力枚举每一位,让它为0,然后往前往后构造序列
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
int minn = 1e18;
for (int i = 0; i < n; i++)
{
int cnt = 0, num = 0;
for (int j = i - 1; j >= 0; j--)
{
int x = (num + a[j] - 1) / a[j];
if (x * a[j] == num) x++;
num = x * a[j];
cnt += x;
}
num = 0;
for (int j = i + 1; j < n; j++)
{
int x = (num + a[j] - 1) / a[j];
if (x * a[j] == num) x++;
num = x * a[j];
cnt += x;
}
minn = min(minn, cnt);
}
cout << minn << '\n';
return 0;
}