Codeforces Round #657 Div. 2
注
类型 | 难度 | |
---|---|---|
1379A. cacius and String | 暴力,关于字符串 | 2 |
1379B. Dubious Cyrpto | 关于数学 | 1 |
1379C. Choosing flowers | 排序 | 3 |
1379A. Acacius and String
解法: 暴力
题意: 给一个长度为n的字符串,由小写字母和‘?‘组成,现在可以把’?‘做替换,问能否使最终结果中’abacaba‘只出现一次。
我的思路:
首先检测原字符串中‘abacaba’出现几次,记录为already
如果already>1, 输出no
如果already=1,把’?‘替换成’d’,然后输出
如果alrady=0,查找到可以成功替换成”abacaba“的位置,就把剩下的‘?’变成‘d’,然后输出。
这时候wa了,wa的原因:
查找到可以成功替换成”abacaba“的位置,应当检查替换后是否能保证already为1,然后再输出。
改正后ac代码如下
#include "bits/stdc++.h"
using namespace std;
string ss,tem;
int n;
const char standard[]="abacaba";
int check(string ff)
{
int cnt=0;
for(int d=0;d+6<n;++d)
{
int suc=1;
for(int k=0;k<=6;++k)
if(standard[k]!=ff[d+k]){suc=0;
break;}
if(suc)++cnt;
if(cnt>1)return cnt;
}
return cnt;
}
int possible(int i)
{
for(int k=0;k<=6;++k)
{
if(ss[i+k]=='?')continue;
if(ss[i+k]!=standard[k])return 0;
}
return 1;
}
int main()
{
// freopen("in.text","r",stdin);
int cas;
scanf("%d",&cas);
while (cas--)
{
cin>>n>>ss;
int already=check(ss);
if(already>1)
{
printf("No\n");
continue;
}
else if(already==1)
{
printf("Yes\n");
for(int i=0;i<n;++i)if(ss[i]=='?')ss[i]='d';
cout<<ss<<endl;
}
else if(already==0)
{
int suc=0;
for(int i=0;i+6<n;++i)
if(possible(i)){
tem=ss;
for(int d=0;d<=6;++d)tem[i+d]=standard[d];
if(check(tem)==1)
{
suc=1;
for(int d=0;d<n;++d)if(tem[d]=='?')tem[d]='d';
break;
}
}
if(suc)cout<<"Yes"<<endl<<tem<<endl;
else cout<<"No"<<endl;
}
}
return 0;
}
1379C Choosing flowers
题意: 有m种花,每种话买一束花的快乐是 a i a_i ai, 买k束花的快乐是 a i + ( k − 1 ) b i a_i+(k-1)b_i ai+(k−1)bi ,现在要买n 束花,问快乐值最大是多少。
思路:
答案必然是很多种a属性花和1种b属性花,why?
假设现在挑选了很多种a属性花,和 b 1 , b 2 b_1,b_2 b1,b2, 那如果 b 1 b_1 b1大于 b 2 b_2 b2,既然无限,为什么要选 b 2 b_2 b2 呢。
那么枚举选 b i b_i bi 种花,则必然选大于 b i b_i bi的a花,因此用前缀和提前计算出。
算法:
-
对花按a属性值排序jiejing
-
枚举 b i b_i bi, 用二分 找出有多少个大于 b i b_i bi的 a i a_i ai,加上对应的前缀和。
由此算法复杂度为 O ( m ∗ l o g ( m ) ) O(m*log(m)) O(m∗log(m))
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int MAXN=1E5+10;
struct re{
ll a,b;
re(ll k1=0,ll k2=0): a(k1),b(k2){}
bool operator< (const re &it)const
{
return a>it.a;
}
};
re flower[MAXN];
ll presum[MAXN];
int main()
{
// freopen("in.text","r",stdin);
int cas,n,m;
scanf("%d",&cas);
while (cas--)
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;++i)scanf("%lld %lld",&flower[i].a,&flower[i].b);
sort(flower+1,flower+1+m);
presum[0]=0;
for(int i=1;i<=m;++i)presum[i]=presum[i-1]+flower[i].a;
ll ans=0;
for(int i=1;i<=m;++i)
{
int xu=upper_bound(flower+1,flower+1+m,re(flower[i].b,0) )-flower-1;
ll now;
if(xu>=n){ now=presum[n];;}
else if(xu<i)
{
now=presum[xu]+flower[i].a+(n-1-xu)*flower[i].b;
} else if(xu>=i)
{
now=presum[xu]+(n-xu)*flower[i].b;
}
ans=max(now,ans);
}
printf("%lld\n",ans);
}
}