1 条题解
-
0tysnd LV 8 MOD @ 2019-01-20 09:37:00
本题是一道贪心题。盖k个板子,可以看成先盖一块板子,然后切k-1刀。而显然,这k-1刀要把最长的k-1段连续的0切掉。可以使用multiset或优先队列或vector存储加sort排序存储每两个1之间0的个数,然后取最大的k-1个减掉。复杂度均为O(nlogn)。本题解给出multiset和vector的代码。
一、multiset#include<iostream> #include<string> #include<set> #include<vector> using namespace std; vector<int> pos;//记录每个陷阱位置 multiset<int,greater<int> > len;//记录相邻两个陷阱之间的安全洞口个数 int main() { int k,p,n; cin>>k>>p>>n; string all; cin>>all; if(p==0)//没有陷阱 { cout<<0<<endl; return 0; } for(int i=0;i<all.size();i++) { if(all[i]=='1') { pos.push_back(i);//记录每个陷阱位置 if(pos.size()>1) { len.insert(*(pos.end()-1)-*(pos.end()-2)-1); } } } int ans=*(pos.end()-1)-*pos.begin()+1-p; int cnt=1; for(multiset<int,greater<int> >::iterator it=len.begin();cnt<k;it++,cnt++) { ans-=*it;//删除最长的k-1段安全的洞口 } cout<<ans<<endl; return 0; }
二、vector+sort
#include<iostream> #include<string> #include<vector> #include<algorithm> using namespace std; vector<int> pos;//记录每个陷阱位置 vector<int> len;//记录相邻两个陷阱之间的安全洞口个数 int main() { int k,p,n; cin>>k>>p>>n; string all; cin>>all; if(p==0)//没有陷阱 { cout<<0<<endl; return 0; } for(int i=0;i<all.size();i++) { if(all[i]=='1') { pos.push_back(i);//记录每个陷阱位置 if(all.size()>1) { len.push_back(*(pos.end()-1)-*(pos.end()-2)-1); } } } int ans=*(pos.end()-1)-*pos.begin()+1-p; sort(len.begin(),len.end(),greater<int>() ); for(int cnt=0;cnt<k-1;cnt++) { ans-=len[cnt];//删除最长的k-1段安全的洞口 } cout<<ans<<endl; return 0; }
- 1
信息
- 难度
- 5
- 分类
- (无)
- 标签
- (无)
- 递交数
- 74
- 已通过
- 23
- 通过率
- 31%
- 被复制
- 4
- 上传者