Logo wuziyue的博客

博客

2023年4月月赛2题解 整合版---by wuziyue

2023-04-16 18:02:59 By wuziyue

Q1(Markdown不太会用)

[题目](http://go.helloworldroom.com:50080/contest/78/problem/12859)

分析一下:for example: 4出现于那些步骤? 答:4,5,8,9,10,11,16,17,18,19,20,21,22,23,33......

分一下类:4.5 / 8 9 10 11 / 16,17,18,19,20,21,22,23,33

进一步发现:这些数字在(x1,y1) (x2,y2)这样的区间中(x2=x1乘(符号怎么打?)2,y2=y1乘2+1)

对于偶数n来说,x1=n,x2=n+1; 对于奇数n来说,x1=n乘2,x2=n乘2+1;(不要忘记n本身未算在内)

不要问我如何发现的

然后,将1至n分为奇数与偶数分别二分,比较奇偶数中大者输出

主要函数:

int se(int l){
    if(l==0) return m+10;
    int ans=0;
    if(l%2==1){
        ans++;
    }
    else l/=2;
    int a1=l,a2=l;
    while(1){
        a1*=2;
        a2*=2;
        a2++;
        if(a1>n){
            return ans;
        }
        if(a2>n){
            ans+=n-a1+1;
            return ans;
        }
        else ans+=a2-a1+1;
    }
}

二分部分:

    int l=1,r=(n+1)/2;
    while(l<r){
        int mid=(l+r)/2+1;
        int sum=se(mid*2-1);
        if(sum>=m){
            l=mid;
        }
        else r=mid-1;
    }//奇数
    l=l*2-1;
    int l2=0,r2=n/2;
    while(l2<r2){
        int mid=(l2+r2)/2+1;
        int sum=se(mid*2);
        if(sum>=m){
            l2=mid;
        }
        else r2=mid-1;
    }
    l2=l2*2;//偶数

Q2 简单题

上代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    scanf("%d",&n);
    int a[n+1],sum=0,ans=0;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    a[0]=-1;
    for(int i=1;i<=n;i++){
        if(a[i]==a[i-1]){
            sum++;
        }
        if(a[i]!=a[i-1]){
            sum=1;
        }
        ans=max(ans,sum);
    }
    printf("%d",ans);
    return 0;
}

Q3 从左至右,从上至下建立坐标,发现了什么?

数字1:横+纵=2;

数字2至3:横+纵=3;

数字4至6:横+纵=4;

懂了?

一号问:

1.先分组:如:样例19:1+2+3+4+5=15, 1+2+3+4+5+6=21, 所以19在第六组 所以横+纵=7

2.找出本组最小数,(如第六组为16)此数位于(1,横+纵-1)(如16位于(1,6))

3.算目标数-最小数=x(19-16=3),由于方正排列规则为向左下,所以目标数位于(1+x,横+纵-1-x)(如19位于(1+3,6-3))

        int n;
        cin>>n;
        int sum=0,d=0,sum2=1;
        while(sum<n){
            d++;
            sum+=d;
            sum2++;
        }
        sum-=d;
        sum++;
        sum2--;
        int a1=1,a2=sum2;
        while(sum!=n){
            sum++;
            a1++;
            a2--;
        }
        cout<<a1<<' '<<a2;

二号问倒推即可 1.得出目标所在组 2.所在组最小值+(横坐标-1)为目标

int x,y;
        cin>>x>>y;
        int sum2=x+y-1;
        int sum=sum2*(sum2-1)/2;
        sum+=x;
        cout<<sum;

评论

鸡蛋鸭蛋萝卜蛋
世界之大,无奇不有
鸡蛋鸭蛋萝卜蛋
每个人的方法都不一样

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。