Codeforces Round #657 Div. 2

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+(k1)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花,因此用前缀和提前计算出。

算法

  1. 对花按a属性值排序jiejing

  2. 枚举 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(mlogm))

#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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是Mally呀!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值