题目描述
Farmer John 有 N 头奶牛排成一列(1≤N≤3⋅100000)。不幸的是,有一种疾病正在传播。
最初,有一些奶牛被感染。每到夜晚,被感染的奶牛会将疾病传播给它左右两边的奶牛(如果这些奶牛存在的话)。一旦奶牛被感染,她就会持续处于感染状态。
经过一些晚上,Farmer John 意识到情况已经失控,因此他对奶牛进行了检测以确定哪些奶牛感染了疾病。请找出最少有多少头奶牛最初可能感染了这种疾病。
输入格式
第一行为一个整数 N,即 Farmer John 拥有的奶牛数量。
接下来一行,包含长度为 N 的由 1 和 0 组成的位串。其中 1 表示一头被感染的奶牛,0 表示一头在经过若干晚之后仍未被感染的奶牛。
输出格式
输出一个整数,表示最少有多少头奶牛可能最初感染了这种疾病。
输入输出样例
输入 1
5 11111
输出 1
1
输入 2
6 011101
输出 2
4
说明/提示
样例解释 1
假设只有中间的奶牛最初被感染。那么,奶牛们将按以下顺序被感染:
- 第 0 晚:00100(第三只奶牛一开始被感染)
- 第 1 晚:01110(第二和第四只奶牛现在被感染了)
- 第 2 晚:11111(第一和第五只奶牛现在被感染了)
- 第 3 晚:11111(所有的奶牛都已经被感染了,没有新的奶牛被感染)
- ……
经过两个或更多的晚上,奶牛们的状态即与输入的状态相符。还有许多其他的初始状态和夜晚数量可能导致了输入的状态,例如:
- 第 0 晚:10001
- 第 1 晚:11011
- 第 2 晚:11111
或者:
- 第 0 晚:01001
- 第 1 晚:11111
或者:
- 第 0 晚:01000
- 第 1 晚:11100
- 第 2 晚:11110
- 第 3 晚:11111
所有这些初始状态中至少有一头奶牛被感染。
样例解释 2
唯一可能导致这个最终状态的初始状态和夜晚数是:没有经过任何夜晚,输入中的四头感染的奶牛都是从最开始就感染了这种疾病。
生化危机,该如何解决。
从题干可知,我们要一开始最少的奶牛染病(真不知道这样干是为了什么,还不如直接治病。)
所以开一个Ylist[ ]用来放y(连续1的数量),然后从外往里削牛,一次一次的削,直到剩下一个或
两个(推导时,可分奇偶)得:day=(y-1)//2
边界问题呢?
我们为了将奶牛的数量压榨到最小,每块连续1的天数越多越好(可怜的奶牛)得:day=y-1
最终的天数得由最小的一块连续的1的day来定(不然呢?)minday=min(daylist)
求完天数,一开始的病牛数怎么求?
由于minday的缘故,每一头初始的奶牛都有一定的感染范围(当minday为2时,范围为5(包括初
始牛))我们要让这个范围尽量的不重叠,但难免有一些小尾巴,(minday为2,有6头牛要感染
时)就还得加一头。cownum=y/(1+2minday) #‘1’就是处理尾巴用的。
这时,可能会出现小数问题,就用math.ceil()把小数向上取整。(例:math.ceil(7.1)= 8)
结束!
import math
lencow=int(input())
a=input()
a1='0'+a+'0'#头尾加零防边界
j=0
m=0
data=[]
dayl=[1000000000000000000]#大数防全零
for i in range(1,lencow+1):#处理y和过程放一起了
if a1[i-1]=='0' and a1[i]=='1':#开头
m=i
if a1[i]=='1' and a1[i+1]=='0':#结尾
data.append(i-m+1)#相减得长度
if m==1 or i==lencow:
day=i-m
else:
day=(i-m)//2
dayl.append(day)
minday=min(dayl)
cownum=0
for i in data:
cownum+=math.ceil(i/(1+2*minday))
print(cownum)
源头
洛谷:9975
USACO:2023年 12月 铜组 问题2