题目:https://codeforces.com/problemset/problem/1520/E
题意:
给你一个字符串包含" . " ," * "。每次如果*旁边有 . 就可以移动一步,求最少多少步可以将*聚集在一起。
题解:
当我们将其他*向中间一个*移动时,步数最少。
先找出中间的*的下标 分成左右两个循环进行判断 后对判断过的 * 进行标记cur,详细看代码。
#include <iostream>
using namespace std;
typedef long long int ll;
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
string s;
cin >> n;
cin >> s;
int cnt = 0;
for (int i = 0; i < n; i++)
{
if (s[i] == '*')
cnt++;
}
cnt = (cnt + 1) / 2;//取中位数位置
int mid = 0;
for (int i = 0; i < n; i++)
{
if (s[i] == '*')
mid++;
if (mid == cnt)
{
mid = i;//标记下标
break;
}
}
ll ans = 0, cur = 0;
for (int i = mid-1; i >= 0; i--)
{
if (s[i] == '*')
{
ans += (mid - 1) - i - cur;//*..**(4-1)-0-1
cur++;
}
}
cur = 0;
for (int i = mid + 1; i < n; i++)
{
if (s[i] == '*')
{
ans += i - (mid + 1) - cur;
cur++;
}
}
cout << ans << endl;
}
}