Codeforces Educational 144 A-C补题

CF edu144 A-C补题

做完的cf打的一般,因为最近忙于物理实验,很久没有做题。脑子也不怎么灵活,所以这场也是犹豫很久才决定打的。赛时速通两题,然后坐牢的比赛结束。rank 2300+ 还算上了一点分。
题目链接

A. Typical Interview Problem 签到
题意:构造一个字符串s,给你一个字符串t,问你t是否是s的子串。
思路:直接构造s,然后用find函数查询一下即可。注意构造s时多构造几位。(很多大佬都wa了一发)。

void Showball() {
  string s="";
   for(int i=1;i<=10000;i++){
    if(i%3==0) s+="F";
    if(i%5==0) s+="B";
   }
  int n;
  cin>>n;
  string t;
  cin>>t;
  if(s.find(t)!=s.npos){
    cout<<"YES"<<endl;
  }else{
    cout<<"NO"<<endl;
  }
}

B. Asterisk-Minor Template 构造
题意:定义一种匹配:给定一个只含有小写字母和’*'组成的字符串。
如果可以通过将‘*’变成任何字符串(可以是空串)使得s=t。那么就称s和t是匹配的。(s中的‘*’数量不能超过字母的数量)。
现在给你两个字符串a和b。问你能否构造出一个字符串s,使得s同时和a与b匹配。

思路:我们可以对a和b字符串进行分类讨论。如果a和b开头相同
那么我们构造字符串 a [ 0 ] + " ∗ " a[0]+"*" a[0]+""即可。同理,如果a和b结尾相同。那么可以构造 " ∗ " + a . b a c k ( ) "*"+a.back() ""+a.back()。对于剩下的情况。由于开头和结尾都不一样,所以我们需要两个"*",那么我们就需要a和b至少有长度为2的公共子串。由于n很小,那么我们直接暴力枚举一遍即可。
构造成 " ∗ " + s u b s t r + " ∗ " "*"+substr+"*" ""+substr+""即可。

void Showball() {
  string a,b;
  cin>>a>>b;
  if(a[0]==b[0]) {
    cout<<"YES"<<endl;
    cout<<a[0]<<"*"<<endl;
    return;
  }
  if(a.back()==b.back()){
    cout<<"YES"<<endl;
    cout<<"*"<<a.back()<<endl;
    return;
  }
  int ok=0;
  string res="";
  for(int i=0;i<a.size()-1;i++){
    string t=a.substr(i,2);
    if(b.find(t)!=b.npos){
        ok=1;
        res=t;
        break;
    }
  }
  if(ok){
    cout<<"YES"<<endl;
    cout<<"*"<<res<<"*"<<endl;
  }
  else cout<<"NO"<<endl;
 
}

C. Maximum Set 思维
题意:给你两个数l和r。要求你去构造一个集合。保证集合中的任何两个元素a和b满足 a整除b或者b整除a。要求求出集合的最大元素数,以及最大元素数的情况下集合的种类数。
思路:首先最大元素数比较好求,就是 l ∗ 2 k ≤ r l*2^k \leq r l2kr满足不等式的最大的 k k k。即 l o g 2 ( r / l ) + 1 log_2(r/l)+1 log2(r/l)+1
对于集合种类数。我们发现最小的数不一定是 l l l,也可以是 l + 1 , l + 2 , . . . l+1,l+2,... l+1,l+2,...。最大可以到多少呢?稍微分析一下,可知最大为 r / 2 k r/2^k r/2k。那么一共有 r / 2 k − l + 1 r/2^k-l+1 r/2kl+1种情况。除了这种情况,我们发现还可以将其中的连续相乘的一位2换成3。举个例子: l ∗ 2 ∗ 2 ∗ 2... ≤ r l*2*2*2...\leq r l222...r。可以换成 l ∗ 3 ∗ 2 ∗ 2 ∗ 2.... ≤ r l*3*2*2*2....\leq r l3222....r,并且最多只能换一个3。因为 3 ∗ 3 > 2 ∗ 2 ∗ 2 3*3>2*2*2 33>222,那么就和最大元素数这个条件相矛盾。那么这种情况的个数就可以类比第一种情况进行求解。 l , l + 1 , . . . r / ( 2 k − 1 ∗ 3 ) l,l+1,...r/(2^{k-1}*3) l,l+1,...r/(2k13),那么一共有 r / ( 2 k − 1 ∗ 3 ) − l + 1 r/(2^{k-1}*3)-l+1 r/(2k13)l+1。又因为我们有 k k k个位置可以换成3。所以最后再乘上3即可。

void Showball() {
  int l,r;
  cin>>l>>r;
  int len = __lg(r/l);
  int maxn=1<<len;
  int res1=max(0,r/maxn-l+1),res2;
  if(maxn>=2) res2=max(0,(r/(maxn*3/2)-l+1))*len;
  cout<<len+1<<" "<<res1+res2<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Showball.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值