题目描述:
现在,你正在玩一个名为放置羊群的游戏,这个游戏的最终目标是需要你将所有 的绵羊排成连续的一排。在一个游戏关卡中,你将得到一个长度为的字符串。这个字符串由字符′.′'.'′.′和字符′∗′'*'′∗′组成,其中,′.′'.'′.′表示空格,′∗′'*'′∗′表示绵羊。如果对应的位置上存在空格,那么,你每一次可以将一只绵羊任意的向左或向右移动一格的位置。
例如:如果现在有一组n=6n=6n=6,字符串为“∗∗.∗..”“**.*..”“∗∗.∗..”的数据,那么,你将可以对其进行以下操作:
先将第4个格子内的绵羊向右移动一格,得到“∗∗..∗.“**..*.“∗∗..∗.
再将第2个格子内的绵羊向右移动一格,得到“∗.∗.∗.”“*.*.*.”“∗.∗.∗.”
再将第1个格子内的绵羊向右移动一格,得到“.∗∗.∗.”“.**.*.”“.∗∗.∗.”
再将第3个格子内的绵羊向右移动一格,得到“.∗.∗∗.”“.*.**.”“.∗.∗∗.”
再将第2个格子内的绵羊向右移动一格,得到“..∗∗∗.”“..***.”“..∗∗∗.”
此时,所有的绵羊都已排成连续的一排,游戏结束。
现在,题目将告诉你每个关卡的情况,请你计算,通过这个关卡最少需要移动多少次?
输入格式:
第一行输入一个数字 t(t≤104)t(t\leq 10^4)t(t≤104) 表示测试的组数。
对于每组测试,第一行输入一个数字 n(n≤106)n(n\leq 10^6)n(n≤106) ,表示字符串的长度。第二行输入一个只包含’.‘和’*'的字符串。
题目保证,对于任何的一个测试文件,nnn 的和不超过 10610^6106
输出格式:
对于任何一场游戏,输出通关最少所需要移动的次数。
样例:
样例输入
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;
}