2413. Social Distancing 1

2413. Social Distancing 1

题目描述

一种新型疾病,COWVID-19,开始在全世界的奶牛之间传播。Farmer John 正在采取尽可能多的预防措施来防止他的牛群被感染。
Farmer John 的牛棚是一个狭长的建筑物,有一排共 N 个牛栏(2≤N≤10^5)。有些牛栏里目前有奶牛,有些目前空着。得知“社交距离”的重要性,Farmer John 希望使得 D 尽可能大,其中 D 为最近的两个有奶牛的牛栏的距离。例如,如果牛栏 3 和 8 是最近的有奶牛的牛栏,那么 D=5。
最近两头奶牛新来到 Farmer John 的牛群,他需要决定将她们分配到哪两个之前空着的牛栏。请求出他如何放置这两头新来的奶牛,使得 D 仍然尽可能大。Farmer John 不能移动任何已有的奶牛;他只想要给新来的奶牛分配牛栏。

输入

输入的第一行包含 N。下一行包含一个长为 N 的字符串,由 0 和 1 组成,描述牛棚里的牛栏。0 表示空着的牛栏,1 表示有奶牛的牛栏。字符串中包含至少两个 0,所以有至少有足够的空间安置两头新来的奶牛。

输出

输出 Farmer John 以最优方案在加入两头新来的奶牛后可以达到的最大 D 值(最近的有奶牛的牛栏之间的距离)。

样例输入

14
10001001000010

样例输出

2

数据范围限制

测试点 1-6 满足 N≤10。
测试点 7-8 满足 N≤100。
测试点 9-11 满足 N≤5000。
测试点 12-15 满足 N≤10^5。

提示

在这个例子中,Farmer John 可以以这样的方式加入奶牛,使得牛栏分配变为 10x010010x0010,其中 x 表示新来的奶牛。此时 D=2。不可能在加入奶牛之后取到更大的 D 值。

题目思路:这道题我们都会一开始想到用一个排序或打擂台来先求出最大及次大的区间,然后分情况讨论就行了。
(当然还有特殊情况~ _我就被WA了一个点93.3 QWQ!

设d表示两头病牛之间距离
情况一(只有一个区间):

  1. 全是0的情况 例如:000000
    就直接把两头牛首尾各放一个 (100001)ans=n-1;
  2. 第一头是感染的,最后一头是感染的 例如:100000 000001
    对于这种情况,我们需要稍微改动一下,d=零的个数*2,ans=a/4;
  3. 首尾都被感染的 例如:100001
    那我们就放在它的三等分点,ans=d/3;

情况二(两个及两个以上区间):

先求出第一大的距离及次大的距离(dis1,dis2);
那么我们的最大距离就等于次大距离/2.
当然不是这么简单。
我们还需考虑一种特殊情况。
例如:10000001001
像这种,普通的话就直接等于3/2.
可直接放在最大区间呢!
那就是7/3,显然更优。
所以我们需要去做个比较(max),最大距离放两头牛的值与各方一头牛。我们求最大距离放两头牛,原理同上。

最后我们还需要与原来所有区间的最小值取min!

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e5+5;
string s;
int n,t,d,x,dis[N],head,tail,minn=MAX;
bool mark;
int main()
{
	fre(socdist);
	cin>>n;	cin>>s;
	for(int i=1;i<n;i++)
	{
		mark=0;
		if(s[i]=='1')
		{
			mark=1;
			d=i-x,x=i;
			if(!t&&s[0]=='0') d*=2,head=d;//例:000001
		}
		else if(i==n-1&&s[i]=='0')
		{
			mark=1;
			d=(i-x)*2;
			if(!t&&s[0]=='0') d=i;    //全为0的情况; 
			tail=d;
		}		
		if(mark) dis[++t]=d;	
	}
	sort(dis+1,dis+1+t);
	dis[t+1]=MAX;  //避免只有两个区间的死循环
	x=1,minn=dis[x];
	//cout<<t<<' '<<dis[t]<<"   "<<dis[t-1]<<endl;
	int ans;
	if(t==1)
	{
		if(s[0]=='0'&&s[n-1]=='0') ans=dis[1];   //全为0的情况;
		else if(s[0]=='1'&&s[n-1]=='1') ans=dis[t]/3; //首尾为1
		else ans=dis[t]/4; //一边为1,10000或000001
	}
	else
	{
		int tt=0;
		ans=dis[t-1]/2;
		if((s[0]=='0'&&dis[t]==head)||(s[n-1]=='0'&&dis[t]==tail)) tt=dis[t]/4;
		else tt=dis[t]/3;
		ans=max(ans,tt);
		while(minn==head||minn==tail) minn=dis[++x];
		ans=min(minn,ans); 
	}
	//cout<<minn<<' '<<ans<<endl;
	cout<<ans<<endl;
	return 0;
}
发布了130 篇原创文章 · 获赞 93 · 访问量 6801

猜你喜欢

转载自blog.csdn.net/bigwinner888/article/details/105441731
今日推荐