网站备案域名备案上海关键词优化按天计费
农夫约翰有 NN 头奶牛排成一排,从左到右依次编号为 1∼N。
不幸的是,有一种传染病正在蔓延。
最开始时,只有一部分奶牛受到感染。
每经过一个晚上,受感染的牛就会将病毒传染给它左右两侧的牛(如果有的话)。
一旦奶牛被感染,它就会一直被感染,无法自愈。
给定一个经过若干个夜晚后的奶牛的整体状态,其中哪些奶牛已经被感染,哪些奶牛尚未被感染统统已知。
请你计算,最开始时就受到感染的奶牛的最小可能数量。
输入格式
第一行包含整数 N。
第二行包含一个长度为 N 的 01 序列,用来表示给定的奶牛的整体状态,其中第 i 个字符如果是 1 则表示第 i 头奶牛已经被感染,如果是 0则表示第 i 头奶牛尚未被感染。
输出格式
一个整数,表示最开始时就受到感染的奶牛的最小可能数量。
数据范围
1≤N≤3×10^5
输入样例1:
5
11111
输出样例1:
1
样例1解释
初始时,任意一头奶牛被感染,一定天数后都可以使得所有奶牛被感染。
输入样例2:
6
011101
输出样例2:
4
样例2解释
唯一一种可能是给定状态是没有经过任何夜晚时所有奶牛的状态,所以输入中被感染的 4 头奶牛都在最开始时就受到感染。
思路:暴力思路是模拟倒推感染,两端被感染的奶牛群可以先从内端递减,其余奶牛群从两边递减。这样最后当不能在减时,在考虑两端的最小奶牛情况。通过模拟的思路后,不难发现最后决定初始最小奶牛数的是(除两端外)当前被感染数最少的奶牛群,借此得出最大的感染天数。这里大致分为二种情况:
- 两端和中间都有被感染的奶的牛群。
- 两端有而中间没有被感染奶的牛群。
- 两端没有而中间有被感染奶的牛群。
第一种情况需要判断最大的感染天数是否大于两端奶牛群数量;第二种情况直接以最小的奶牛群数量-1为最大感染天数;第三种情况可套用一种。最后附上AC代码,太菜勿喷/(ㄒoㄒ)/~~
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=3e5+10;
int n,cnt;
int a[N];
int b[N];
string s;
int cmp(int a,int b){return a<b;
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>n;cin>>s;int flag=0;for(int i=0;i<s.size();i++){a[i+1]=s[i]-'0';if(s[i]=='1'){if(!flag)cnt++,b[cnt]=1;else b[cnt]++;flag=1;}else flag=0;}for(int i=1;i<=cnt;i++)cout<<b[i]<<' ';cout<<endl;int ans=0,r=1,l=cnt,mod;int da=0;if(s[0]=='1')r=r+1;if(s[s.size()-1]=='1')l=cnt-1;if(r<=l){sort(b+r,b+l+1,cmp);if(b[r]%2)da=b[r]/2;else da=b[r]/2-1;}if(da){mod=da;if(r==2){if(mod>=b[1])mod=b[1]-1;}if(l==cnt-1){if(mod>=b[cnt])mod=b[cnt]-1;}mod=2*mod+1;for(int i=1;i<=cnt;i++)if(b[i]%mod)ans+=b[i]/mod+1;else ans+=b[i]/mod;}else{mod=min(b[1],b[cnt])-1;mod=2*mod+1;for(int i=1;i<=cnt;i++)if(b[i]%mod)ans+=b[i]/mod+1;else ans+=b[i]/mod;}cout<<da<<endl;cout<<mod<<endl;cout<<ans;return 0;
}