[codeforces][gym102062]2018 Battle of Brains

抽了小半天空做了一下这套题…

A.
简单坑题,由于英文不好被题意gank了,判断(a+b+c+d)*2是否大于等于n+1…

#include<bits/stdc++.h>
#define LiangJiaJun main
using namespace std;
int T,n,a,b,c,d;
int w33ha(){
    scanf("%d%d%d%d%d",&n,&a,&b,&c,&d);
    if(((a+b+c+d)<<1)<n+1)puts("No");
    else puts("Yes");
    return 0;
}
int LiangJiaJun(){
    scanf("%d",&T);
    while(T--)w33ha();
    return 0;
}

B.
有T组询问,每次询问两个数字M和D,求问能装下质量为M,密度为D的液体的容器的最小表面积。

很显然这个容器是个球体,我们先求出液体的体积V,这个可以通过密度公式 D = M / V D = M/V D=M/V来求。
然后球体体积已知之后我们求出球体半径 r ( V = 4 / 3 ∗ p i ∗ ( r 3 ) ) r(V = 4/3*pi*(r^3)) r(V=4/3pi(r3)),然后球体表面积就是 4 ∗ p i ∗ ( r 2 ) 4* pi *(r^2) 4pi(r2)
tips: cbrt(x)是求 x x x的立方根的函数。

#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
using namespace std;
int T;
ll m,d;
int w33ha(int CASE){
    scanf("%lld%lld",&m,&d);
    double V=1.0*m/(1.0*d);
    double r=cbrt(V*3/4/pi);
    printf("Case %d: %.4lf\n",CASE,4*pi*r*r);
    return 0;
}
int LiangJiaJun(){
    scanf("%d",&T);
    for(int i=1;i<=T;i++)w33ha(i);
    return 0;
}

C.
在这里插入图片描述
给出半圆ADBCA的半径 r r r,求图中阴影部分面积。

瞎算算就知道是 ( r 2 ) / 4 (r^2)/4 (r2)/4

#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
using namespace std;
double r;
int w33ha(int CASE){
    scanf("%lf",&r);
    printf("Case %d: %.4lf\n",CASE,(r*r)/4.0);
    return 0;
}
int LiangJiaJun(){
    int T;
    scanf("%d",&T);
    for(int i=1;i<=T;i++)w33ha(i);
    return 0;
}

D.
T ( T &lt; = 10000 ) T(T&lt;=10000) TT<=10000次询问,每组询问询问一个 N ( N &lt; = 1 0 9 ) N(N&lt;=10^9) NN<=109,要求输出第 N N N小的长度为奇数的回文数字。
限定:第一小的回文数字是 1 1 1

这道题可以先预处理长度为x的回文数字的数量,这个可以通过递推解决(长度+1,数量*10)。
然后先确定当前询问的N的对应的回文数字的位数,然后从第一位向中间慢慢统计答案即可。

#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
using namespace std;
ll sum[104];
int n,ans[104];
int w33ha(int CASE){
    scanf("%d",&n);
    int np=1;
    while(n>sum[np]){
        n-=sum[np];
        np+=2;
    }
    int half=np/2+1;
    for(int i=1;i<=half;i++){
        int now=0;
        if(i==1)now++;
        ll civ=1;
        for(int j=i+1;j<=half;j++)civ*=10;
        while(n>civ){
            ++now;
            n-=civ;
        }
        ans[i]=now;
    }
    printf("Case %d: ",CASE);
    for(int i=1;i<=half;i++)printf("%d",ans[i]);
    for(int i=half-1;i;i--)printf("%d",ans[i]);
    puts("");
    return 0;
}
int prework(){
    sum[1]=9;
    for(int i=3;sum[i-2]<=1000000000LL;i+=2){
        int pre=i-2;
        sum[i]=sum[pre]*10;
    }
    return 0;
}
int LiangJiaJun(){
    prework();
    int T;scanf("%d",&T);
    for(int i=1;i<=T;i++)w33ha(i);
    return 0;
}

E.
给定一个 d ( 0 &lt; = d &lt; = 60 ) d(0&lt;=d&lt;=60) d0<=d<=60一个 x ( 0 &lt; = x &lt; = 1 0 18 ) x(0&lt;=x&lt;=10^{18}) x0<=x<=1018,你位于一个数轴上,这个数周只有非负整数。刚开始你位于数轴的 0 0 0位置,每次你可以向正方向或者负方向跳 2 d 2^d 2d的长度,每跳一次, d d d的值减少 1 1 1,当 d d d小于 0 0 0的时候,你就不能跳了。询问给定的 d d d能否在几次跳跃之后到达 x x x点。如果可以,则输出YES和至少跳几次,否则输出NO。

我们可以知道每个数字都是可以被分解成若干个不同2的幂的加和。首先 d + 1 d+1 d+1如果大于等于x二进制分解后的长度cnt,则一定有解,否则无解。然后接下来求至少跳几次,从高位到低位,如果 d + 1 &gt; = c n t d+1&gt;=cnt d+1>=cnt那么这个是一定要跳的(第一次往正方向,其余次都是负方向),之后就是如果当前位置开始往地位都已经没有 1 1 1了,那么就停止跳跃,否则继续跳。注意特判 x = = 0 x==0 x==0的情况。

#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
using namespace std;
ll d;
ll x,poc[74],soc[74];
int w33ha(int CASE){
    scanf("%lld%lld",&d,&x);
    if(x==0){
        return printf("Case %d: YES 0\n",CASE),0;
    }
    int cnt=0;
    while(x){
        poc[++cnt]=(x&1);
        x>>=1;
    }
    d++;
    soc[0]=0;
    for(int i=1;i<=cnt;i++)soc[i]=soc[i-1]+poc[i];
    bool flag=0;
    if(d<cnt)flag=1;
    int ans=0;
    while(d>=cnt){
        ans++;
        d--;
    }
    cnt--;
    while(cnt){
        if(poc[cnt]==1){
            ans++;
        }
        else{
            if(soc[cnt]==0)break;
            else ans++;
        }
        cnt--;
    }
    if(flag)printf("Case %d: NO\n",CASE);
    else printf("Case %d: YES %d\n",CASE,ans);
    return 0;
}
int LiangJiaJun(){
    int T;scanf("%d",&T);
    for(int i=1;i<=T;i++)w33ha(i);
    return 0;
}

F.
题意:
给了一个生成图的方法:给定一个 n n n,先创建出所有他的因数 ( 大 于 1 ) (大于1) (1)的节点。然后对于每个节点,把它和它的因数之间连边。
T T T组询问,每次询问一个 n n n,问从 1 1 1~ n n n中随机选出一个数字 i i i,使得它生成的图是一棵树的概率(用分数表示)。

通过性质可以知道,如果一个数字质因数分解的结果中有超过2个质数,那么这个数字生成的图就不是树。那么只要预处理小于等于1000000的数字中质因数个数小于等于2的数字有几个即可,查询就是log级别(指求最大公因数)的了。

#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
using namespace std;
int t[1000004];
int pri[1000004];
int cnt,cnt1000,ans[1000004];
int monk(int x){
    int now=x,cp=1;
    while(cp<=cnt1000&&pri[cp]<=now&&now>1){
        if(now%pri[cp]==0){
            now/=pri[cp];
            if(t[now])return 0;
            else return 1;
        }
        cp++;
    }
    return 1;
}
int prework(){
    t[1]=1;t[0]=1;
    cnt=0;
    for(int i=1;i<=1000000;i++){
        if(!t[i]){
            for(int j=i<<1;j<=1000000;j+=i)t[j]=1;
        }
    }
    for(int i=1;i<=1000000;i++){
        if(!t[i]){
            pri[++cnt]=i;
            ans[i]=1;
            if(1LL*i*i<=1000000)ans[i*i]=1;

        }
    }
    cnt1000=cnt;
    while(pri[cnt1000]>1000)cnt1000--;
    ans[1]=1;
    for(int i=2;i<=1000000;i++){
        if(ans[i])continue;
        ans[i]=monk(i);
    }
    for(int i=1;i<=1000000;i++)ans[i]+=ans[i-1];
}
int n;
int w33ha(int CASE){
    scanf("%d",&n);
    int d=__gcd(n,ans[n]);
    printf("Case %d: %d/%d\n",CASE,ans[n]/d,n/d);
    return 0;
}
int LiangJiaJun(){
    prework();
    int T;scanf("%d",&T);
    for(int i=1;i<=T;i++)w33ha(i);
    return 0;
}

G.
统计一个字符串(长度<= 1 0 5 10^5 105)的所有子串的价值之和对 1 0 9 + 7 10^9+7 109+7取模的结果。
一个串的价值被定义为:

"它的所有字符的ascii码值 乘以 串的长度"

我们可以考虑对于一个位置上的字符来说,它需要乘以多少。
对于处于 i i i位置的字符,能够覆盖它的子串的起点显然位于 1 1 1 i i i,而且对于不同的起点,子串的数量相同,都是 ( n − i + 1 ) (n-i+1) (ni+1)。而且对于以 j j j为起点的子串,能够覆盖 i i i的所有子串的长度之和为 ( l + i − 2 ∗ ( j − 1 ) ) ∗ ( l − i + 1 ) / 2 (l+i-2*(j-1))*(l-i+1)/2 (l+i2(j1))(li+1)/2然后这个是一个以 ( l − i + 1 ) (l-i+1) (li+1)为差值的等差数列,然后对于每个 i i i来说就可以求了它要乘多少了。记得long long

#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
#define MOD 1000000007LL
using namespace std;
char s[100004];
int w33ha(int CASE){
    int l;
    scanf("%d",&l);
    scanf("%s",s+1);
    ll ans=0;
    for(int i=1;i<=l;i++){
        ll bg=1LL*(l+i)*(l-i+1)>>1;
        ll ed=1LL*(l-i+2)*(l-i+1)>>1;
        ll cnt=1LL*(bg+ed)*i>>1;
        ans=(ans+((ll)s[i])*cnt)%MOD;
    }
    printf("Case %d: %lld\n",CASE,ans);
    return 0;
}
int LiangJiaJun(){
    int T;scanf("%d",&T);
    for(int i=1;i<=T;i++)w33ha(i);
    return 0;
}

H.
给一个字符串(长度 &lt; = 6000 &lt;=6000 <=6000),和 q q q组询问,询问一个区间和一个数字maxvalue,对这个区间进行一个操作,区间的价值设定为:区间中每个字符和它以这个区间的中心的对称字符的ascii码的差的绝对值之和。如果区间价值 &gt; m a x v a l u e &gt;maxvalue >maxvalue,则去掉这个区间的两端的元素,直到区间价值 &lt; = m a x v a l u e &lt;=maxvalue <=maxvalue最后输出满足区间价值 &lt; = m a x v a l u e &lt;=maxvalue <=maxvalue的最长的串的长度。

预处理之后对于每个询问二分删除元素的个数即可。细节有点多,注意。

#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
#define MOD 1000000007LL
#define INF 1999122700
using namespace std;
char s[6004];
int n;
int mp[6004][6004];
int prework(){
    for(int i=1;i<=n;i++){
        for(int l=i,r=i;l>0&&r<=n;l--,r++){
            mp[l][r]=mp[l+1][r-1]+abs(0+s[l]-s[r]);
        }
        for(int l=i,r=i+1;l>0&&r<=n;l--,r++){
            mp[l][r]=mp[l+1][r-1]+abs(0+s[l]-s[r]);
        }
    }
    return 0;
}
int query(int a,int b,int val){
    int ans=INF,l=0,r=b-a,mid;
    while(l<=r){
        mid=(l+r)>>1;
        int cl=a+mid,cr=b-mid,calc;
        if(cl>=cr)calc=0;
        else calc=mp[cl][cr];
        if(calc<=val){
            ans=mid;
            r=mid-1;
        }
        else{
            l=mid+1;
        }
    }
    return b-a+1-(ans<<1);
}
int w33ha(int CASE){
    scanf("%s",s+1);
    n=strlen(s+1);
    prework();
    int q;scanf("%d",&q);
    while(q--){
        int a,b,val;
        scanf("%d%d%d",&a,&b,&val);
        printf("%d\n",query(a,b,val));
    }
    return 0;
}
int LiangJiaJun(){
    memset(mp,0,sizeof(mp));
    int T;scanf("%d",&T);
    for(int i=1;i<=T;i++)w33ha(i);
    return 0;
}

I.
咕咕咕

J.
咕咕咕

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。GymCodeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.csdn.net/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.csdn.net/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.csdn.net/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值