B. Yet Another Bookshelf(思维)Codeforces Round #677 (Div. 3)

原题链接: https://codeforces.com/contest/1433/problem/B

在这里插入图片描述
测试样例

input
5
7
0 0 1 0 1 0 1
3
1 0 0
5
1 1 0 0 1
6
1 0 0 0 0 1
5
1 1 0 1 1
output
2
0
2
4
1

Note

In the first test case of the example, you can shift the segment [3;3] to the right and the segment [4;5] to the right. After all moves, the books form the contiguous segment [5;7]. So the answer is 2.

In the second test case of the example, you have nothing to do, all the books on the bookshelf form the contiguous segment already.

In the third test case of the example, you can shift the segment [5;5] to the left and then the segment [4;4] to the left again. After all moves, the books form the contiguous segment [1;3]. So the answer is 2.

In the fourth test case of the example, you can shift the segment [1;1] to the right, the segment [2;2] to the right, the segment [6;6] to the left and then the segment [5;5] to the left. After all moves, the books form the contiguous segment [3;4]. So the answer is 4.

In the fifth test case of the example, you can shift the segment [1;2] to the right. After all moves, the books form the contiguous segment [2;5]. So the answer is 1.

题意: 有一个 n n n大小的一维书架,从 1 1 1 n n n开始编号,给出了书架的相关信息,即 a i a_i ai 1 1 1则代表有书, a i a_i ai 0 0 0则代表没有书。现在你可以进行一次操作,选择一个区间段 [ l : r ] [l:r] [l:r],进行其中任意一个:

  • 将该区间所有有书的格子向右移。移的前题是 r + 1 ≤ n    a n d    a r + 1 = 1 r+1\leq n\space\space and \space\space a_{r+1}=1 r+1n  and  ar+1=1
  • 将该区间所有有书的格子向左移。移的前题是 l − 1 ≥ 1    a n d    a l − 1 = 1 l-1≥ 1\space\space and \space\space a_{l-1}=1 l11  and  al1=1

问你至少需要进行多少次操作次数才可以使得书架上的书是连续放置的。

解题思路: 这道题有一定的技巧性,首先我们要理解就是我们选的区间越大是不是相对越好?因为我们进行一次操作可以移很多次,那么我们还要知道的一点就是我们是不是要选择一个参考点,即我们将所有书都移到它的旁边,这个参考点自然也是放置书的,且为了方便我们会选择第一个放置书的位置,即让后面所有放置的书都移到它的右边。 这样自然就很抽象了,我们发现,起决定性的就是离参考点最远的位置。为什么呢?因为我们每次选择这样的区间都会把这些书往参考点移,而最慢达成连续的也是取决于离参考点最远的位置。那么,我们该怎么计算最小操作次数呢?是不是最远点距参考点的距离 − 1 -1 1?显然不是,我们发现,在参考点和最选距离点之间的其他放置书的点,它们会填补间隔,即我们实际要进行的操作就只有这之间有多少个没有放书的格子数量。那么我们有很多方法可以统计这其中没有放书的格子数量,我这里是通过减法来实现的。具体看代码。

AC代码

/*
*邮箱:[email protected]
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<bits/stdc++.h>	//POJ不支持

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//


int t,n;
int a[55];
int main(){
    
    
	//freopen("in.txt", "r", stdin);//提交的时候要注释掉
	IOS;
	while(cin>>t){
    
    
		while(t--){
    
    
			cin>>n;
			vector<int> pos;
			rep(i,1,n){
    
    
				cin>>a[i];
				if(a[i]){
    
    
					pos.push_back(i);
				}
			}
			int len=pos.size();
			int cnt=pos[len-1]-pos[0]-1-(len-2);
			cout<<cnt<<endl;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/hzf0701/article/details/109193019