题目链接:E. Moving Chips
题意:
只有 * 和 . 的2行n列的图,每次可以将任意一个 *移动一格,当两个 *相遇
时将合并为一个,问最少需要多少不能将所有 *合并为一个
思路:
贪心,对于每一排,看离他最近的前面的*在哪,用last1,last2 表示
对于每个点,我们可以贪心的把后面的 * 先移到他这,然后再让他往前移,也可以让后面的 * 在他移的路径路径上跟他合并
如果是前者,更新完这个点后,lasti更新为i,如果是后者,last1 last2都更新为i,而如何决定为那种情况就看更新这个点前last1 last2 的关系
如果之前 last1==last2,肯定就是第一种情况,因为同时更新last1last2得多走一步,也只是让后面的点最多少走一步,而如果后面的点没少走,就不是最优解
如果之前last1!=last2但last1 last2 中最大值是和当前*在一行,也是第一种情况,原因一样
反之就同时更新last1 last2 ,这样保证该点移动步数最小的情况下,后面的点移动步数也最小
有个特殊情况就是同一列两个都是*,这样就先把他们合并,再往前走,因为合并后在哪行总步数一样,所以只用考虑 last1 last2 最大值就好
Code:
#include <bits/stdc++.h>
#define debug freopen("_in.txt", "r", stdin);
// #define debug freopen("_in.txt", "r", stdin), freopen("_out.txt", "w", stdout);
typedef long long ll;
typedef unsigned long long ull;
typedef struct Node *bintree;
using namespace std;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll maxn = 1e6 + 10;
const ll maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const double pi = acos(-1);
const double eps = 1e-8;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
ll T;
ll n, m, maxx;
char str[10][maxn];
void solve()
{
scanf("%lld", &n);
for (ll i = 1; i <= 2; i++)
{
scanf("%s", str[i] + 1);
}
ll cnt = 0, flag = 0, last1 = -1, last2 = -1;
for (ll i = 1; i <= n; i++)
{
if (str[1][i] == '*' && str[2][i] == '*')
{
if (!flag)
{
cnt++;
flag = 1;
last1 = last2 = i;
}
else
{
ll maxx = max(last1, last2);
cnt++;
cnt += i - maxx;
last1 = last2 = i;
}
}
else if (str[1][i] == '*')
{
if(!flag)
{
flag=1;
last1=i;
continue;
}
ll maxx = max(last1, last2);
ll minn = min(last1, last2);
if (maxx == minn)
{
cnt += i - maxx;
last1 = i;
}
else
{
if (maxx == last1)
{
cnt += i - maxx;
last1 = i;
}
else
{
cnt += i - maxx;
cnt++;
last1 = i;
last2 = i;
}
}
}
else if (str[2][i] == '*')
{
if(!flag)
{
flag=1;
last2=i;
continue;
}
ll maxx = max(last1, last2);
ll minn = min(last1, last2);
if (maxx == minn)
{
cnt += i - maxx;
last2 = i;
}
else
{
if (maxx == last2)
{
cnt += i - maxx;
last2 = i;
}
else
{
cnt += i - maxx;
cnt++;
last1 = i;
last2 = i;
}
}
}
}
printf("%lld\n", cnt);
}
int main()
{
// debug;
// T = 1;
scanf("%lld", &T);
while (T--)
{
solve();
}
}
Tips:
语言表达能力有限,欢迎各位聚聚提出建议、问题,有不懂的地方也欢迎提问,我会尽力解答