A. Two Frogs
题意:
从1到n一共n个坐标点,a和b分别在不同的点上, 每回合都必须向左或者向右移动一个坐标,二者不能重叠,由a先移动,一方不能移动则另一方获胜,a能否获胜。
思路:
显然,二者的间距为偶数时a总能获胜。
AC code:
void solve() {
int n, a, b;
cin >> n >> a >> b;
int d = abs(a - b);
if (d % 2) {
cout << "NO" << endl;
} else {
cout << "YES" << endl;
}
}
B. Crafting
题意:
有n种材料,每种材料现有 a i a_i ai单位,制作物品需要每种材料至少 b i b_i bi单位,每1单位材料可以花费其他(n-1)种材料各1单位进行兑换,是否可以成功制作物品。
思路:
模拟,若当前材料不够,记录需要其他材料提供 b [ i ] − a [ i ] b[i] - a[i] b[i]−a[i]单位,需要额外提供的单位总和记录为 n o w now now,对于统计后的每一个单位,若在提供其他单位兑换材料后仍制作物品,即 ( a [ i ] − n o w < b [ i ] ) (a[i] - now < b[i]) (a[i]−now<b[i])时,当前材料可以满足条件。
其中 n o w now now会额外减去为当前 a i a_i ai 提供的单位,需要在记录时额外添加 2 ∗ ( b [ i ] − a [ i ] ) 2 * (b[i] - a[i]) 2∗(b[i]−a[i]) 。
AC code:
void solve() {
int n; cin >> n;
vector<int> a(n), b(n);
int cnt = 1e9;
for (int i = 0; i < n; i ++) cin >> a[i];
int now = 0;
for (int i = 0; i < n; i ++) {
cin >> b[i];
if (a[i] < b[i]) {
now += b[i] - a[i];
a[i] += 2 * (b[i] - a[i]);
}
}
for (int i = 0; i < n; i ++) {
if (a[i] - now < b[i]) {
cout << "NO" << endl;
return;
}
}
cout << "YES" << endl;
}
C. The Trail
题意:
有一篇n*m的山区,每个单元格为不同的高度,现在该区域被修改,有一条由(n+m-1)个单元格组成的由坐标(1,1)到坐标(n, m)的路径,移动方式只有向下和向右两种,移动路径会被标记高度为0,现在给出路径,还原原山区矩阵。
对于原山区矩阵,每一条横纵单元格的和均相等。
思路:
每一条横纵单元格的和均为0,然后进行模拟;
首先记录每一条横纵单元格的当前和,根据移动位置修改当前位置的数据;
若为纵向移动,则修改移动前行总和为0,若为横向移动,则修改移动前纵向总和为0;
AC code:
void solve() {
int n, m;
cin >> n >> m;
string s;
cin >> s;
vector<vector<int>> mat(n + 1, vector<int>(m + 1, 0));
vector<int> row(n + 1, 0), col(m + 1, 0);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> mat[i][j];
row[i] += mat[i][j];
col[j] += mat[i][j];
}
}
int x = 1, y = 1;
for (int i = 0; i < s.size(); i++) {
if (s[i] != 'D') {
mat[x][y] = -col[y];
row[x] -= col[y];
col[y] = 0;
y ++;
} else {
mat[x][y] = -row[x];
col[y] -= row[x];
row[x] = 0;
x ++;
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (i == n && j == m) mat[i][j] = -col[m];
cout << mat[i][j] << " ";
}
cout << endl;
}
}
D. Scarecrow
题意:
一只乌鸦当前在数轴0点位置,数轴上有n个点有稻草人,稻草人每秒可以向左或右移动一个单位;
乌鸦与坐标小于它的稻草人直接必须距离至少k个单位距离,否则就会瞬间传送(传送不耗时);
传送条件为,若当前稻草人单位x < 乌鸦单位y,且 y - x < k,则乌鸦瞬间传送到 y + k的位置;
现在乌鸦需要到达第m单位,需要的最短时间为多少。
注意,稻草人可能花费0.5s移动0.5个单位时,乌鸦就会触发条件瞬间移动!
思路:
模拟,初始时乌鸦在0点,最左边的稻草人至少需要花费a[0]单位时间到达0处,使得乌鸦瞬移到k点;
记录乌鸦当前位置now以及花费时间time;
若当前位置a[i] + time的稻草人依然小于等于当前乌鸦位置now,则直接瞬移到 a[i] + time + k点处;
若当前稻草人可以通过time的时间到达乌鸦当前位置,则乌鸦瞬移到now + k处
否则,需要额外的时间来触发乌鸦的移动,此时乌鸦左右均有稻草人,左侧稻草人距离乌鸦一定为k,乌鸦需要移动到超过右侧稻草人,则需要的时间为 (a[i] - time - now) / 2,因为两边的稻草人是相对移动的,当乌鸦触碰到右侧稻草人的瞬间可以移动到其+k的位置,此时乌鸦的位置为 now + (a[i] - time - now) / 2 + k;
直到乌鸦移动到终点,注意,输出答案是需要将浮点数转换为整数。
AC code:
void solve() {
int n, k, aim; cin >> n >> k >> aim;
vector<int> a(n);
for (int i = 0; i < n; i ++) cin >> a[i];
double time = a[0], now = k;
for (int i = 1; i < n; i ++) {
if (now >= aim) break;
if (a[i] + time <= now) {
now = a[i] + time + k;
} else {
if (abs(a[i] - now) <= time) {
now += k;
} else {
double tmp = a[i] - time - now;
tmp /= 2;
time += tmp;
now = now + tmp + k;
}
}
}
if (now < aim) {
time += aim - now;
}
cout << (int)(time * 2) << endl;
}