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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现