2020 年 “联想杯”全国高校程序设计在线邀请赛暨第三届上海理工大学程序设计竞赛(A 签到,B签到,C签到,D思维+MST,G单调栈,H暴力,L思维暴力)

题目链接

官方视频讲解

A. Archmage

签到题

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define per(i,a,b) for(int i=a;i>=(b);--i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline ll read()
{
	ll x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}
const int N=1e3+10;
double x[N],y[N],z[N];
int n;
double dis(double x,double y,double z)
{
    return sqrt(x * x + y * y + z * z);
}
int main()
{
    int _ = read();while(_--)
    {
        ll n = read(), m = read(), x = read(), y = read();
        if(y >= x){
        	if(n>=x) printf("%lld\n",m);
        	else printf("%lld\n",m-1);
            continue;
        }
        ll sum = n + (m - 1) * y;
        ll ans = sum / x;
        ans = min(ans,m);
        printf("%lld\n",ans);
    }
}

B. Bamboo Leaf Rhapsody

签到题

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define per(i,a,b) for(int i=a;i>=(b);--i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline ll read()
{
	ll x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}
const int N=1e3+10;
double x[N],y[N],z[N];
int n;
double dis(double x,double y,double z)
{
    return sqrt(x*x+y*y+z*z);
}
int main()
{
    n=read();

    rep(i,1,n) cin>>x[i]>>y[i]>>z[i];
    double ans=dis(x[1],y[1],z[1]);
    rep(i,1,n)
    {
        ans=min(ans,dis(x[i],y[i],z[i]));
    }
    printf("%.3f\n",ans);
}

C. Cheat Sheet

签到题

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define per(i,a,b) for(int i=a;i>=(b);--i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline ll read()
{
	ll x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}
const int N=1e3+10;

int n,m;
int a[N];

string t[N];
int main()
{
    n = read(),m = read();

    rep(i,1,m) cin>>t[i];

    sort(t+1,t+1+m);
    m=unique(t+1,t+1+m)-t-1;

    rep(i,1,m) a[i]=t[i].size();
    sort(a+1,a+1+m);



    int ans=0;
    rep(i,1,m)
    {
        //printf("i:%d sz:%d\n",i,a[i]);
        if(n>=a[i]) n-=a[i],ans++;
        else break;
        if(i!=m) n--;
    }


    printf("%d\n",ans);
}

D. Disaster Recovery

这题我傻了,我先比较min(x,y)再比较max(x,y)了,粗略证明:

ai+bi  跟  aj+bj 比大小,先比大的   max(ai,bi)>max(aj,bj)   成立  又ai=ai-1+ai-2  那么aj+bj  最大最大也就只能得到ai  但我的ai还加了个bi。

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define rep(i,a,b) for(int i=(a);i<=(b);i++)

using namespace std;

inline ll read()
{
	ll x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}

const int N=1e6+10;
struct node
{
    int u,v;
    pair<int,int>w;
    bool operator <(const node &o)const{
        return w<o.w;
    }
}a[N];
int fa[N],du[N],n,m;
int fin(int x)
{
    if(fa[x]!=x) fa[x]=fin(fa[x]);
    return fa[x];
}




int main()
{
    n=read(),m=read();
    rep(i,1,n) fa[i]=i;

    rep(i,1,m){
        int u=read(),v=read();
        a[i]={u,v,make_pair(max(u,v),min(u,v))};
    }

    sort(a+1,a+1+m);

    rep(i,1,m)
    {
        int f1=fin(a[i].u);
        int f2=fin(a[i].v);
        if(f1==f2) continue;
        du[a[i].u]++;
        du[a[i].v]++;
        fa[f1]=f2;
    }

    int ans=0;
    rep(i,1,n) ans=max(ans,du[i]);
    printf("%d\n",ans);
}

G. Gentle Jena

这题看b站视频补的。

1、单独考虑b[i]的贡献就是 bi*li*ri   li 是 以bi为最小值时的左端点到i的距离长度

2、那么新增一个b[i] 对前面所有的小于当前b[i]的b[j]们 的贡献就是增加了一个 bj*lj
3、bj*lj*rj=>bj*lj*(rj+1)  //这里 代码中用now维护
4、i新增的贡献就是li*bi

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define fi first
#define se second
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const ll mod=998244353;
inline ll read()
{
	ll x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}
const int N=1e7+10;
ll n,p,x,y,z,b;

int main()
{
    n=read(),p=read(),x=read(),y=read(),z=read(),b=read();
    ll now=0,ans=0,sum=0;
    // 单独考虑b[i]的贡献就是 bi*li*ri   li 是 以bi为最小值时的左端点到i的距离长度
    //那么新增一个b[i] 对前面所有的小于当前b[i]的b[j]们 的贡献就是增加了一个 bj*lj
    //bj*lj*rj=>bj*lj*(rj+1)  //这里 代码中用now维护
    //i新增的贡献就是li*bi
    for(int i=1;i<=n;++i){
        ll len=1;
        while(sta.size()&&sta.top().first>=b){
            len+=sta.top().second;
            now=(now-sta.top().first*sta.top().second%mod+mod)%mod;
            sta.pop();
        }
        //printf("len:%lld now:%lld sum:%lld\n",len,now,sum);
        sta.push(make_pair(b,len));
        now=(now+b*len%mod)%mod;

        sum=(sum+now)%mod;
        //printf("len:%lld now:%lld sum:%lld\n\n",len,now,sum);
        ans=ans^sum;
        b=(x*sum%p+y*b%p+z)%p;
    }
    printf("%lld\n",ans);
}

H. Hay Mower

做法:时间复杂度可以达到:k*max(n,m) 你就知道怎么做了,维护每行 每列的最大时间就可以了。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const ll mod=998244353;
inline ll read()
{
	ll x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}
const int N=5e2+10;
ll a[N][N],n,m,k;
ll row[N],col[N];
void add(ll &x,ll y)
{
    x=(x+y)%mod;
}
int main()
{
    n=read(),m=read(),k=read();
    rep(i,1,n) rep(j,1,m) a[i][j]=read()%mod;

    ll ans=0;
    while(k--)
    {
        char s[2];
        scanf("%s",s);ll x=read(),t=read();

        if(s[0]=='r'){
            ll bs=row[x];
            for(int i=1;i<=m;++i){
                add(ans,(t-max(bs,col[i]))%mod*a[x][i]%mod);
            }
            row[x]=t;
        }
        else{
            ll bs=col[x];
            for(int i=1;i<=n;++i){
                add(ans,(t-max(bs,row[i]))%mod*a[i][x]%mod);
            }
            col[x]=t;
        }
        //printf("%lld\n",ans);
    }
    printf("%lld\n",ans);

}

L. Lottery Tickets

做法:枚举后两个数,后两个数尽量的小,也就是大的数 尽量在高位输出就可以了。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define fi first
#define se second
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

inline ll read()
{
	ll x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}
int a[12],sum;
int main()
{
    int _=read();while(_--)
    {
        sum=0;
        rep(i,0,9) {
            a[i]=read();sum+=a[i];
        }
        if(sum==a[0]){puts("0");continue;}

        pair<int,int>ans={-1,-1};
        rep(i,0,9){
            rep(j,0,9){
                if((i*10+j)%4!=0) continue;
                if(!a[i]||!a[j]) continue;
                if(i==j&&a[i]<2) continue;

                ///printf("i:%d j:%d\n",i,j);
                if(ans.fi==-1){
                    ans={i,j};
                    continue;
                }
                if(max(i,j)<max(ans.fi,ans.se)){
                    ans={i,j};
                }
                else if(min(i,j)<min(ans.fi,ans.se)){
                    ans={i,j};
                }
                else if(max(i,j)==max(ans.fi,ans.se)&&min(i,j)==min(ans.fi,ans.se)){
                    ///printf("i:%d j:%d fi:%d se:%d\n",i,j,ans.fi,ans.se);
                    ans={max(i,j),min(i,j)};
                }
            }
        }

        if(ans.fi==-1){
            if(a[8]) puts("8");
            else if(a[4]) puts("4");
            else if(a[0]) puts("0");
            else puts("-1");
        }
        else{
            a[ans.fi]--;
            a[ans.se]--;
            for(int i=9;i>=0;--i){

                while(a[i]--) printf("%d",i);

            }
            printf("%d%d\n",ans.fi,ans.se);
        }




    }
}

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/106452438