5438.密病牛

题目链接:https://www.acwing.com/problem/content/description/5441/

题意:

每过一天病牛可以往左右扩散。
给定若干天后这群牛的状态,求最初的病牛最小个数

思路:

显然经过天数越多,病牛扩散的越厉害,最初需要的病牛数就越少。

所以先求经过最长天数:当最左边/右边有病牛时,res=cnt-1.否则,当cnt为奇数时,res=(cnt-1)/2,当cnt为偶数时,res=(cnt-2)/2,res取min,因为需要满足每过一天往左右扩散的条件

对于每堆病牛,一头病牛经过i天能最多使2*i+1(包括自己)生病,所以每堆计数一下cnt/(2*i+1)(向上取整)

#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define pb push_back
#define endl "\n"
#define fi first
#define se second
//#pragma GCC optimize(3)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const ll llmax=LLONG_MAX;
const int maxn=1e5+5;
const int mod=1e9+7;
int n;
string s;
signed main()
{
ios::sync_with_stdio(false),cin.tie(0);
cin>>n>>s;
int cnt=0;
int res=inf;
bool f=false;
rep(i,0,s.size()-1){
if(s[i]=='1'){
cnt++;
if(i==0)f=true;
}
if(s[i]=='0'&&cnt){
if(f){
f=false;
if(cnt%2==0){
res=min(res,cnt-1);
}else{
res=min(res,cnt-1);
}
}else{
if(cnt%2==0){
res=min(res,(cnt-2)/2);
}else{
res=min(res,(cnt-1)/2);
}
}
cnt=0;
}
}
if(cnt){
if(cnt%2==0){
res=min(res,cnt-1);
}else{
res=min(res,cnt-1);
}
}
cnt=0;
int ans=0;
for(int i=0;i<s.size();i++){
if(s[i]=='1'){
cnt++;
}
if(s[i]=='0'&&cnt){
ans+=(int)ceil(cnt*1.0/(2*res+1));
cnt=0;
}
}
if(cnt)ans+=(int)ceil(cnt*1.0/(2*res+1));
cout<<ans;
return 0;
}
posted @   Marinaco  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
//雪花飘落效果
点击右上角即可分享
微信分享提示