P9975 [USACO23DEC] Cowntact Tracing 2 B 题解
思路
为了让最开始感染的牛尽量少,我们要让传染的天数尽量多。我们可以先求出这个天数,再根据天数来倒推最开始最少的感染牛数。
通过思考可以发现,连续
让我们假设这个求出来的天数是
最后是要注意边界,因为边界的情况与中间不太一样。在边界,连续
代码
#include<iostream>
#include<vector>
#include<cmath>
#define ll long long
#define in inline
#define re register
using namespace std;
const ll maxn = 3e5 + 5;
in ll read(){
char ch;
ll f = 1, r = 0;
ch = getchar();
while(ch > '9' || ch < '0'){ if(ch == '-') f = -1; ch = getchar();}
while(ch <= '9' && ch >= '0') r = (r << 3) + (r << 1) + (ch ^ 48), ch = getchar();
return r * f;
}
in void write(ll f){
if(f < 0) f = -f, putchar('-');
if(f > 9) write(f / 10);
putchar(f % 10 + '0');
return;
}
ll n = read(), a[maxn], ans[maxn], mn = maxn, last, cnt;
vector <ll> st, ed;//记录每一段连续感染奶牛的起点和终点
int main(){
for(re ll i = 1; i <= n; ++i){
scanf("%1d", &a[i]);
if(a[i]){
last++;
if(!a[i - 1]) st.push_back(i);//一段连续感染奶牛的开始
} else if(!a[i] && last){
if(st[st.size() - 1] == 1) mn = min(mn, i - 2);//注意边界
else mn = min(mn, (last - 1) / 2);//计算最多天数
last = 0, ed.push_back(i - 1);
}
}
if(last) mn = min(mn, last - 1), ed.push_back(n);//最后别忘了
for(re ll i = 0; i < st.size(); ++i) cnt += ceil(1.0 * (ed[i] - st[i] + 1) / (2 * mn + 1));//计算牛数
write(cnt);
return 0;
}