Educational Codeforces Round 144 (Rated for Div. 2)
Educational Codeforces Round 144 (Rated for Div. 2)
A
题意
从1开始,当数为3的倍数输出‘F',为5的倍数输出'B' ,都是两者倍数输出'FB'.
思路
模拟下就可以看出规律,以'FBFFBFFB'为循环,记得要复制3次,因为它最长为10,最多在3个循环节中
代码
void solve()
{
cin>>n;
string s;
cin>>s;
string t="FBFFBFFB";
t=t+t+t;
if(t.find(s)!=-1) cout<<"YES\n";
else cout<<"NO\n";
}
B
题意
还是自己去看题吧。
思路
如果a,b首字母或者尾字母相同,就直接对应输出
如果不是以上两种情况,就遍历,看是否有a,b中长度为2的串是否有相同的。
为什么有长度为2的串相同就可以输出?
因为 除了最上面那种情况,其余情况都可以化为\(*xy*\)的形式。
代码
void solve()
{
cin>>a;
cin>>b;
//cout<<a<<" "<<b<<endl;
if(a[0]==b[0])
{
cout<<"YES\n";
cout<<a[0]<<"*"<<endl;
return;
}
n=a.size(),m=b.size();
if(a[n-1]==b[m-1])
{
cout<<"YES\n";
cout<<"*"<<a[n-1]<<endl;
return;
}
for(int i=0;i<n-1;i++)
{
string s=a.substr(i,2);
if(b.find(s)!=-1)
{
cout<<"YES\n";
cout<<"*"<<s<<"*"<<endl;
return;
}
}
cout<<"NO\n";
}
C
题意
对于一个集合,如果它的任意两个元素都能 有 其中一个能整除另一个,那么它是好的。
问在区间[L,R] 中由这个区间某些数内构成的好的集合的最长长度是多少,以及且满足这个长度的好集合有多少个
思路
对于一个集合 它是好的而且达到最长 ,那么它应该为\({1,2,4,8,16...}\)(这里是除以它的公因数),对于题目中的第一个问题,显然由把L迭代以下就能求出最大长度。
第二问:以集合\({1,2,4,8,16,32}\)(以下成为基础集合)为例
它为什么不能继续延长?因为32的最小倍数64>R 。
那如果它的\(\frac {3}{2}\)倍48<=R呢?则集合的某个元素\(x_i\)可以变为\(x_i=x_{i-1}*3\),之后的元素依然是乘2。
则这个集合可以为\(1,3,6,12,24,48\)(第二位变了)
可以为\(1,2,6,12,24,48\)(第三位变了),除开头那个元素外其他都可以变,有len-1种(len为集合长度)
假设好集合最长长度为base,则这样的基础集合由\(\frac{r}{2^{base}}-l+1\)种,而这其中基础集合存在可变情况的集合有\(\frac{r}{3*2^{base-1}}-l+1\)种
为什么是\(\frac {3}{2}\)倍这么奇怪的数字? 因为这是我的理解,很多大佬都是直接看出有的地方可以变成3倍而不是2倍,我还是太弱了。
代码
void solve()
{
int l,r;
cin>>l>>r;
int ans1=0,ans2=0;
int base=1,len=0;
while(l*base<=r) base*=2,len++;
base/=2;
if(len==1) {ans1=1,ans2=r-l+1;}
else
{
ans1=len;
ans2=(r/base-l+1)%mod;
base=base*3/2;
ans2=(ans2+(max(0ll,r/base-l+1))*(ans1-1)%mod)%mod;
}
cout<<ans1<<" "<<ans2<<endl;
}