Codeforces Round #681 (Div. 2, based on VK Cup 2019-2020 - Final)
题意:0代表没有炸弹,1代表有炸弹,点燃一个炸弹可以引起连锁反应,花费是a,可以在没没有炸弹的地方添加炸弹,花费为吧,然后构成连续的炸弹,引起连锁反应。
思路:统计每段连续的1的起始位置和结束位置。然后相邻的两段的1中间的0的个数为 ans ,如果 b * ans < = a, 说明填炸弹更划算,如果 b * ans > a, 则把前面的连续的炸弹花费 a 引爆就行 ,后面的在和下一个连续的1进行配对。(需要特判全是0的情况)。
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=1e5+10; int main() { int t; cin>>t; while(t--){ int a,b; pair<int,int>q[N]; cin>>a>>b; string s; cin>>s; int l=0; int _size=s.size(); int falge=0; for(int i=0; i<_size; i++){ if(s[i]=='1') falge=1; if(s[i]=='1'&&i==0){ q[l].first=i; } else if(s[i]=='1'&&s[i-1]=='0'){ q[l].first=i; } if(s[i]=='1'&&i==_size-1){ q[l].second=i; l++; } else if(s[i]=='1'&&s[i+1]=='0'){ q[l].second=i; l++; } } int ans=0; for(int i=1;i<l;i++){ int sum=(q[i].first-q[i-1].second-1)*b; if(sum<=a){ ans+=sum; } if(sum>a){ ans+=a; } } if(falge==1) cout<<ans+a<<endl; else cout<<"0"<<endl; } return 0; }
题意:给定n,和数组an,bn。
选ai或bi。ai是快递员自己送餐来,时间不叠加,bi是自己去取,时间要叠加,问最少多少时间能将这些快递全部取了。
思路: 按照快递员送餐的时间进行排序,如果送餐的时间相同就把自己取餐的时间短的放后面。因为我们最大时间取决于我们快递时间最长以及自己去取的时间,因而我们只要一直增大自己取的时间,减少最大快递时间,即可得到最短时间.
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+10; int cmp(pair<int,int>a,pair<int,int>b){ if(a.first!=b.first)return a.first<b.first; else return a.second>b.second; } int main() { int t; cin>>t; while(t--) { int n; pair<ll,ll>p[N]; cin>>n; for(int i=0;i<n;i++){ cin>>p[i].first; } for(int i=0;i<n;i++){ cin>>p[i].second; } sort(p,p+n,cmp); p[-1].first=0; for(int i=0;i<n;i++) // cout<<p[i].first<<"****"<<p[i].second<<endl; ll Max=0; ll sum=0; int i; for( i=n-1;i>=0;i--){ if(p[i].first>=sum+p[i].second){ sum+= p[i].second ; } else break; } cout<<max(p[i].first,sum)<<endl; } return 0; }