第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛(部分题解)

版权声明:转载的时候注明来源就好啦(○’ω’○) https://blog.csdn.net/Murphyc/article/details/74915095

唉,好久没更新博客了,说明我这段时间在学习上都懈怠了Σ( ° △ °|||)︴

昨天打了场金马赛,这网络…..我真的是无力吐槽…..

前三题都是大水题,就不挂代码了;

D-快速幂取模裸题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1000000007;
ll MOD(ll a,ll b,ll mod)
{
    ll ret=1;
    ll tmp=a;
    while(b)
    {
       if(b&0x1)
           ret=ret*tmp%mod;
       tmp=tmp*tmp%mod;
       b>>=1;
    }
    return ret;
}
ll sum=0;
ll n;
int main()
{
    while(scanf("%lld",&n)!=EOF)
    {
        ll ans=MOD(2,n,mod);
        ans--;
        printf("%lld\n",ans);
    }
}

E-字符串模拟或者java大数或者高精度都可以

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char s[20];
int m;
//char bian[100000005];
int main()
{
    while(scanf("%s",s)!=EOF)
    {
        ll k=0;
        char a[100005];
        scanf("%d",&m);
        int len=strlen(s);
        ll sum=0;
        for(int i=0;i<len;i++)
        {
            ll bei=1;
            for(int j=1;j<=len-i-1;j++)
                bei*=26;
            //printf("%d\n",bei);
            sum+=(s[i]-'a')*bei;
            //printf("%d\n",sum);
        }
        //printf("%d\n",sum);
        if(sum==0)
            printf("0");
        while(sum)
        {
            if(sum<m)
            {
                while(sum)
                {
                    a[k]=sum%10+'0';
                    sum/=10;
                    k++;
                    break;
                }
            }
            if(sum==m)
            {
                a[k]='0';
                k++;
                a[k]='1';
                k++;
                break;
            }
            int mod=sum%m;
            if(mod!=0)
            {
                while(mod)
                {
                    a[k]=mod%10+'0';
                    mod/=10;
                    k++;
                }
            }
            else
            {
                a[k]='0';
                k++;
            }
            //printf("%d\n",sum);
            sum/=m;
        }
        //printf("%c\n",a[0]);
        for(int i=k-1;i>=0;i--)
        {
            if(a[i]=='0'&&i==k-1)
                continue;
            else
                printf("%c",a[i]);
        }
        printf("\n");
    }
}

F-lower_bound或者upper_bound二分暴搜过,自己写的二分效率会更高些。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
int n;
int a[100005];
int dp1[100005];
int dp2[100005];
int la[1000005];
int lb[1000005];
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(dp1,0x3f3f3f3f,sizeof(dp1));
        memset(dp2,0x3f3f3f3f,sizeof(dp2));
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        {
            *lower_bound(dp1+1,dp1+1+n,a[i])=a[i];
            la[i]=lower_bound(dp1+1,dp1+1+n,0x3f3f3f3f)-(dp1+1);
        }
        for(int i=n;i>=0;i--)
        {
            *lower_bound(dp2+1,dp2+1+n,a[i])=a[i];
            lb[i]=lower_bound(dp2+1,dp2+1+n,0x3f3f3f3f)-(dp2+1);
        }
        int chang=1;
        for(int i=1;i<=n;i++)
        {
            chang=max(min(lb[i],la[i])*2-1,chang);
        }
        printf("%d\n",chang);
    }
}

K-购买装备
昨天写的时候被吓了一跳,总感觉会有坑,就一直没开….赛后补题没想到这么简单 ( ̄▽ ̄”)

大概就是一开始最先选取价格最低的装备,这样能保证能够买最多的装备,然后再找出自己属性值最低的装备去和没有被购买的属性值最高的装备比较,看看是不是没买的属性值比我级最低的高,如果把属性值最低的装备卖了后钱够的话就买下,反之不做操作;

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int zu;
int n,m;

struct edge
{
    int val;
    int cost;
    bool operator < (const edge &b)const
    {
        return val==b.val ? cost<b.cost: val>b.val;
    }
}a[100005];

bool cmp(edge a,edge b)
{
    return a.cost==b.cost ? a.val>b.val : a.cost<b.cost;
}

int main()
{
    scanf("%d",&zu);
    while(zu--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%d%d",&a[i].val,&a[i].cost);
        sort(a,a+n,cmp);
        priority_queue<edge> q;
        for(int i=0;i<n;i++)
        {
            if(m<a[i].cost)
                break;
            else
            {
                m-=a[i].cost;
                q.push(a[i]);
            }
        }
        for(int i=q.size();i<n;i++)
        {
            if(q.top().val>=a[i].val)
                continue;
            else
            {
                if(m-a[i].cost+q.top().cost>=0)
                {
                    m+=q.top().cost;
                    m-=a[i].cost;
                    q.pop();
                    q.push(a[i]);
                }
            }
        }
        printf("%d %d\n",q.size(),q.top().val);
    }
}

H-调和序列—-那个直接看上去,K的数据范围看着估计吓倒一片人 (⊙□⊙)
然而,n只有2e5,直接扔到vector里离线处理一下就好。
这题….我又wa了大概五遍……最后是胡大佬过来帮我找错,发现时s>=n这个判定我少写了“=”,因为我是从0开始的啊啊啊啊啊,
最大只到n-1
٩(×̯×)۶

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int zu;
int n,m;
ll a[100005];
vector<ll>v[100005];
ll k;
ll s;

bool cmp(ll a,ll b)
{
    return a>b;
}
int main()
{
    scanf("%d",&zu);
    while(zu--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            v[i].clear();
        }
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<=(n-1)/i;j++)
            {
                v[i].push_back(a[i*j]);
            }
            sort(v[i].begin(),v[i].end(),cmp);
        }
        for(int i=0;i<m;i++)
        {
            scanf("%lld%lld",&k,&s);
            if(k>=n)//别忘了等号啊啊啊啊啊啊!
            {
                if(s==1)
                    printf("%lld\n",a[0]);
                else
                    printf("-1\n");
            }
            else
            {
                if(v[k].size()<s)
                    printf("-1\n");
                else
                    printf("%lld\n",v[k][s-1]);
            }
        }
    }
}
展开阅读全文

没有更多推荐了,返回首页