USACO铜 2023 12月 奶牛得病问题

题目描述

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

加油,菜鸟终将成为大佬
  • 43
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值