题目描述:
现在,你正在玩一个名为放置羊群的游戏,这个游戏的最终目标是需要你将所有 的绵羊排成连续的一排。在一个游戏关卡中,你将得到一个长度为的字符串。这个字符串由字符 ′ . ′ '.' ′.′和字符 ′ ∗ ′ '*' ′∗′组成,其中, ′ . ′ '.' ′.′表示空格, ′ ∗ ′ '*' ′∗′表示绵羊。如果对应的位置上存在空格,那么,你每一次可以将一只绵羊任意的向左或向右移动一格的位置。
例如:如果现在有一组 n = 6 n=6 n=6,字符串为 “ ∗ ∗ . ∗ . . ” “**.*..” “∗∗.∗..”的数据,那么,你将可以对其进行以下操作:
先将第4个格子内的绵羊向右移动一格,得到 “ ∗ ∗ . . ∗ . “**..*. “∗∗..∗.
再将第2个格子内的绵羊向右移动一格,得到 “ ∗ . ∗ . ∗ . ” “*.*.*.” “∗.∗.∗.”
再将第1个格子内的绵羊向右移动一格,得到 “ . ∗ ∗ . ∗ . ” “.**.*.” “.∗∗.∗.”
再将第3个格子内的绵羊向右移动一格,得到 “ . ∗ . ∗ ∗ . ” “.*.**.” “.∗.∗∗.”
再将第2个格子内的绵羊向右移动一格,得到 “ . . ∗ ∗ ∗ . ” “..***.” “..∗∗∗.”
此时,所有的绵羊都已排成连续的一排,游戏结束。
现在,题目将告诉你每个关卡的情况,请你计算,通过这个关卡最少需要移动多少次?
输入格式:
第一行输入一个数字 t ( t ≤ 1 0 4 ) t(t\leq 10^4) t(t≤104) 表示测试的组数。
对于每组测试,第一行输入一个数字 n ( n ≤ 1 0 6 ) n(n\leq 10^6) n(n≤106) ,表示字符串的长度。第二行输入一个只包含’.‘和’*'的字符串。
题目保证,对于任何的一个测试文件, n n n 的和不超过 1 0 6 10^6 106
输出格式:
对于任何一场游戏,输出通关最少所需要移动的次数。
样例:
样例输入
5 6 **.*.. 5 ***** 3 .*. 3 ... 10 *.*...*.**
样例输出
1 0 0 0 9
思路:
零点分段
AC代码:
#include<bits/stdc++.h>
using namespace std;
long long t, n, cnt, a[1000005], ans;
char s;
int main(){
scanf("%lld", &t);
while(t --){
cnt = ans = 0;
scanf("%lld\n", &n);
for(int i = 1; i <=n ; i ++){
s = getchar();
if(s == '*')a[++ cnt] = i;
}
if(cnt == n || cnt == 0 || cnt == 1){
printf("0\n");
continue;
}
int mid=cnt + 1 >> 1;
for(int i = 1; i <= cnt; i ++){
if(i < mid)ans += a[mid] - a[i] - 1 - mid + i + 1;
if(i > mid)ans += a[i] - a[mid] - 1 - i + mid + 1;
}
printf("%lld\n", ans);
}
return 0;
}