Educational Codeforces Round 128 (Rated for Div. 2) E. Moving Chips(玄学)
链接
题意:给一个
2
∗
n
2*n
2∗n的
∗
.
*.
∗.矩阵,你要随便选起点,
∗
*
∗走过一个
∗
*
∗就会覆盖它,问最少多少步只剩一个
∗
*
∗。
思路:因为只有两列,我们直接分类讨论对于每一列的状态怎么从上一个转移,为了方便,设
∗
*
∗为1,
.
.
.为0,有一个变量idx1和idx2,这一行代表走到这一列的步数,此时是所有的
∗
*
∗全被覆盖
①当当前状态为
00
00
00的时候,idx1和idx2直接走过来就行,直接++。
②当当前状态为
10
10
10的时候,第一行有需要走的,所以我们第一行的idx1,要么直接++,要么从第二行的
i
d
x
2
+
2
idx2+2
idx2+2来,因为它需要向右走一步,向上走一步。
③当前状态为
01
01
01的情况和②相同。
④状态为
11
11
11,为了吃掉所有的
∗
*
∗,idx1和idx2都要走两步,所以就是为
m
i
n
(
i
d
x
1
,
i
d
x
2
)
+
2
min(idx1,idx2)+2
min(idx1,idx2)+2
最后输出
a
n
s
−
1
ans-1
ans−1
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin >> T;
while (T--) {
int n;
string s1, s2;
cin >> n;
cin >> s1 >> s2;
int idx1 = -1, idx2 = -1, ans = 0;
int f = 1;
for (int i = 0; i < n; i++) {
if (f && s1[i] == '.' && s2[i] == '.') continue;
f = 0;
if (s1[i] != '*' && s2[i] != '*') {
idx1++, idx2++;
}
if (s1[i] == '*' && s2[i] == '*') {
idx1 = idx2 = min(idx1, idx2) + 2;
ans = min({idx1, idx2});
}
if (s1[i] == '*' && s2[i] != '*') {
int a = idx1, b = idx2;
idx1 = ans = min(a + 1, b + 2);
idx2 = min(idx1, idx2) + 2;
}
if (s1[i] != '*' && s2[i] == '*') {
int a = idx1, b = idx2;
idx2 = ans = min(a + 2, b + 1);
idx1 = min(idx1, idx2) + 2;
}
}
cout << ans << endl;
}
return 0;
}