放置羊群(sheep)

这是一个关于放置羊群的游戏,目标是将所有绵羊排成一排。玩家每次可以移动一只绵羊一格,题目给出了不同关卡的字符串布局,并要求计算最少移动次数。样例展示了具体的操作过程和输出格式。解决方案采用了零点分段的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

现在,你正在玩一个名为放置羊群的游戏,这个游戏的最终目标是需要你将所有 的绵羊排成连续的一排。在一个游戏关卡中,你将得到一个长度为的字符串。这个字符串由字符 ′ . ′ '.' .和字符 ′ ∗ ′ '*' 组成,其中, ′ . ′ '.' .表示空格, ′ ∗ ′ '*' 表示绵羊。如果对应的位置上存在空格,那么,你每一次可以将一只绵羊任意的向左或向右移动一格的位置。
例如:如果现在有一组 n = 6 n=6 n=6,字符串为 “ ∗ ∗ . ∗ . . ” “**.*..” ...的数据,那么,你将可以对其进行以下操作:
先将第4个格子内的绵羊向右移动一格,得到 “ ∗ ∗ . . ∗ . “**..*. ...
再将第2个格子内的绵羊向右移动一格,得到 “ ∗ . ∗ . ∗ . ” “*.*.*.” ...
再将第1个格子内的绵羊向右移动一格,得到 “ . ∗ ∗ . ∗ . ” “.**.*.” ...
再将第3个格子内的绵羊向右移动一格,得到 “ . ∗ . ∗ ∗ . ” “.*.**.” ...
再将第2个格子内的绵羊向右移动一格,得到 “ . . ∗ ∗ ∗ . ” “..***.” ...
此时,所有的绵羊都已排成连续的一排,游戏结束。
现在,题目将告诉你每个关卡的情况,请你计算,通过这个关卡最少需要移动多少次?

输入格式:

第一行输入一个数字 t ( t ≤ 1 0 4 ) t(t\leq 10^4) t(t104) 表示测试的组数。
对于每组测试,第一行输入一个数字 n ( n ≤ 1 0 6 ) n(n\leq 10^6) n(n106) ,表示字符串的长度。第二行输入一个只包含’.‘和’*'的字符串。
题目保证,对于任何的一个测试文件, 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值