华为杯山理校赛

去年的比赛了
昨天浏览山理的官网,偶然看到的
有一说一,山理对算法竞赛的重视程度确实高
别人学校的OJ真的好
唉。。。
注册了账号,当成模拟赛打了一把,自闭。。。

A题

在这里插入图片描述
签到题

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
    
    
    int a,b;
    cin>>a>>b;
    if(b%2!=0)
    {
    
    
        if(a%2!=0)
        {
    
    cout<<"black"<<endl;}
        else
        {
    
    cout<<"white"<<endl;}
    }
    else
    {
    
    
        if(a%2==0)
        {
    
    cout<<"black"<<endl;}
        else
        {
    
    cout<<"white"<<endl;}
    }
    return 0;
}

B题

在这里插入图片描述
签到题

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

int a[10];
int main()
{
    
    
    for(int i=0;i<5;i++)
    {
    
    
        cin>>a[i];
    }
    sort(a,a+5);
    cout<<a[0]+a[1]+a[2]+a[3]<<" "<<a[1]+a[2]+a[3]+a[4]<<endl;
    return 0;
}

C题

在这里插入图片描述
签到题

#include <bits/stdc++.h>
#define ll long long
using namespace std;

string s="SDUTACM";
int main()
{
    
    
    int n;
    cin>>n;
    int k=0;
    for(int i=1;i<=n;i++)
    {
    
    
        if(i==1||i==n)
        {
    
    
            for(int j=1;j<=n;j++)
            {
    
    
                cout<<s[k];
                k++;k%=7;
            }
            cout<<endl;
        }
        else
        {
    
    
            cout<<s[k];k++;k%=7;
            for(int i=1;i<=n-2;i++)
            {
    
    cout<<" ";}
            cout<<s[k]<<endl;k++;k%=7;
        }
    }
    return 0;
}

E题

在这里插入图片描述
在这里插入图片描述
递归题,按照题意写个递归即可

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

int a[100];
void down(int x);
void up(int x);
void down(int x)
{
    
    
    if(a[x]==0){
    
    return;}
    if(x==1)
    {
    
    a[1]=0;cout<<"1 DOWN"<<endl;return;}
    for(int j=x-1;j>=1;j--)
    {
    
    
        if(j==x-1)
        {
    
    
            if(a[j]==0)
            {
    
    up(j);}
        }
        else
        {
    
    
            if(a[j]==1)
            {
    
    down(j);}
        }
    }
    a[x]=0;cout<<x<<" DOWN"<<endl;
}
void up(int x)
{
    
    
    if(a[x]==1){
    
    return;}
    if(x==1)
    {
    
    a[1]=1;cout<<"1 UP"<<endl;return;}
    for(int j=x-1;j>=1;j--)
    {
    
    
        if(j==x-1)
        {
    
    
            if(a[j]==0)
            {
    
    up(j);}
        }
        else
        {
    
    
            if(a[j]==1)
            {
    
    down(j);}
        }
    }
    a[x]=1;cout<<x<<" UP"<<endl;
}
int main()
{
    
    
    for(int i=1;i<100;i++)
    {
    
    a[i]=1;}
    int n;
    cin>>n;
    if(n==1)
    {
    
    cout<<"1 DOWN"<<endl;return 0;}
    for(int i=n;i>=1;i--)
    {
    
    
        down(i);
    }
    return 0;
}

F题

在这里插入图片描述
在这里插入图片描述
最开始想的是扩欧,但扩欧写到一半就写不下去了,太tm难写了,然后换成bfs搜索过了。
代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

struct node
{
    
    
    ll w,cnt,time;
};
queue<node>q;
ll vis[100005];
ll flag,lpl,ans;
void bfs(ll a,ll b,ll n,ll m)
{
    
    
    node e;
    e.w=1;
    e.cnt=0;
    vis[1]=lpl;
    q.push(e);
    while(!q.empty())
    {
    
    
        node r=q.front();q.pop();
        node ee;
        ee.w=r.w+a;
        ee.cnt=r.cnt+1;
        if(ee.w>n)
        {
    
    ee.w-=n;}
        if(ee.w==m)
        {
    
    flag=1;ans=ee.cnt;return;}
        if(vis[ee.w]!=lpl)
        {
    
    
            vis[ee.w]=lpl;
            q.push(ee);
        }
        /
        node u;
        u.w=r.w+b;
        u.cnt=r.cnt+1;
        if(u.w>n)
        {
    
    u.w-=n;}
        if(u.w==m)
        {
    
    flag=1;ans=u.cnt;return;}
        if(vis[u.w]!=lpl)
        {
    
    
            vis[u.w]=lpl;
            q.push(u);
        }
    }
}
void init()
{
    
    
    while(!q.empty())
    {
    
    q.pop();}
}
int main()
{
    
    
    ll t,n,m,a,b;
    cin>>t;
    while(t--)
    {
    
    
        init();
        lpl++;
        flag=0;ans=0;
        cin>>n>>m;
        cin>>a>>b;
        if(m==1)
        {
    
    cout<<"YES"<<endl<<"0"<<endl;continue;}
        bfs(a,b,n,m);
        if(flag==0)
        {
    
    
            cout<<"NO"<<endl;
        }
        else
        {
    
    
            cout<<"YES"<<endl;
            cout<<ans<<endl;
        }
    }
    return 0;
}

G题

在这里插入图片描述
排序+贪心

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

ll a[100005];
ll vis[100005];
struct node
{
    
    
    ll w,id;
}q[100005];
bool cmp(node a,node b)
{
    
    
    if(a.w>b.w)
    {
    
    return 1;}
    if(a.w==b.w)
    {
    
    
        if(a.id>b.id)
        {
    
    return 1;}
        return 0;
    }
    return 0;
}
int main()
{
    
    
    ll n,x,y;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    
    
        cin>>x>>y;
        a[i]=x+y;
        q[i].w=a[i];
        q[i].id=i;
    }
    sort(q+1,q+1+n,cmp);
    ll st=1,ans=0;
    for(int i=1;i<=n;i++)
    {
    
    
        if(vis[q[i].id]==0)
        {
    
    
            ll op=0,cnt=0;
            while(st<q[i].id)
            {
    
    
                vis[st]=1;
                op+=a[st];
                cnt++;
                st++;
            }
            vis[st]=1;
            ans+=cnt*a[st]-op;
            st++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

H题

在这里插入图片描述
一开始用线段树超时了,这道题是看了题解才过的(丢人),否则我真没发现一个数进行若干次Xh(x)操作后会变成13且不再变化。。。。傻乎乎的我还推了半天公式。。。。
代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

struct node
{
    
    
    ll l,r,pre;
    ll flg;
}sum[1000006];
ll a[1000006],oo=1;
ll digit(ll x)
{
    
    
    ll ans=0;
    while(x>0)
    {
    
    ans+=x%10;
    x/=10;}
    return ans;
}
void build(ll l,ll r,ll os)
{
    
    
    sum[os].l=l;
    sum[os].r=r;
    if(l==r)
    {
    
    
        sum[os].pre=a[oo++];
        if(sum[os].pre==13){
    
    sum[os].flg=1;}
        return;
    }
    ll mid=(l+r)/2;
    build(l,mid,os*2);
    build(mid+1,r,os*2+1);
    sum[os].pre=sum[os*2].pre+sum[os*2+1].pre;
    sum[os].flg=(sum[os*2].flg)&(sum[os*2+1].flg);
}
void change(ll x,ll y,ll os)
{
    
    
    if(x<=sum[os].l&&y>=sum[os].r)
    {
    
    
        if(sum[os].flg==1)
        {
    
    return;}
        if(sum[os].l==sum[os].r)
        {
    
    
            sum[os].pre=3*digit(sum[os].pre)+1;
            if(sum[os].pre==13){
    
    sum[os].flg=1;}
            return;
        }
    }
    ll mid=(sum[os].l+sum[os].r)/2;
    if(x<=mid)
    {
    
    change(x,y,os*2);}
    if(y>mid)
    {
    
    change(x,y,os*2+1);}
    sum[os].pre=sum[os*2].pre+sum[os*2+1].pre;
    sum[os].flg=(sum[os*2].flg)&(sum[os*2+1].flg);
}
ll query(ll x,ll y,ll os)
{
    
    
    if(x<=sum[os].l&&y>=sum[os].r)
    {
    
    return sum[os].pre;}
    ll ans=0;
    ll mid=(sum[os].l+sum[os].r)/2;
    if(x<=mid)
    {
    
    ans+=query(x,y,os*2);}
    if(y>mid)
    {
    
    ans+=query(x,y,os*2+1);}
    return ans;
}
int main()
{
    
    
    ll n,m,l,r,op;
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
    
    scanf("%lld",&a[i]);}
    build(1,n,1);
    scanf("%lld",&m);
    while(m--)
    {
    
    
        scanf("%lld %lld %lld",&op,&l,&r);
        if(op==2)
        {
    
    
            change(l,r,1);
        }
        if(op==1)
        {
    
    
            printf("%lld\n",query(l,r,1));
        }
    }
    return 0;
}

J题

在这里插入图片描述
数据小,暴力即可

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

//double pi=acos(-1);
ll vis[10000];
int main()
{
    
    
    ll n,m;
    char s[100][505];
    scanf("%lld %lld",&n,&m);
    for(int i=0;i<n;i++)
    {
    
    scanf("%s",s[i]);}
    for(int i=0;i<n;i++)
    {
    
    
        for(int j=i+1;j<n;j++)
        {
    
    
            ll cnt=0;
            for(int k=0;k<m;k++)
            {
    
    
                if(s[i][k]=='1'||s[j][k]=='1')
                {
    
    cnt++;}
            }
            vis[cnt]++;
        }
    }
    for(ll i=999;i>=0;i--)
    {
    
    
        if(vis[i]>0)
        {
    
    
            printf("%lld\n",i);
            printf("%lld\n",vis[i]);
            break;
        }
    }
    return 0;
}

K题在这里插入图片描述

签到题

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

double pi=acos(-1);
int main()
{
    
    
    double a,b;
    cin>>a>>b;
    double cr=pi*(a*a+b*b)/4.0;
    double ans=cr-a*b;
    printf("%.3lf\n",ans);
    return 0;
}

自身水平还是不行啊

猜你喜欢

转载自blog.csdn.net/qq_43781431/article/details/106252739