第四届辽宁省大学生程序设计竞赛部分题解

发布时间 2023-11-01 19:06:32作者: Beater_1117

2023辽宁省赛

A:欢迎来到辽宁省赛

题目描述

小Z躺在床上看了看表 , 现在是13:30 , 2023辽宁省大学生程序设计竞赛的报名将会在 14:00 截止。
然而不急 , 省赛的参赛队伍还没有向他提交名单。小Z知道 , 只要 3 分钟他就可以完成报名 , 完成汇款。
现在他想知道 , 队伍要在多少分钟内向他提交完名单。(如有巧合 , 纯属雷同)

输入描述:

输出描述:

思路

签到题,直接输出即可

AC代码

27

B:胜率

题目描述

某个公平竞技手游中有胜率的概念,胜率是一个百分数,等于在游戏中获胜的局数除以参与的游戏局数。在本题中,我们将胜率进行四舍五入,修约为两位小数。

比如参加了 7 局游戏,赢了 3 局,那么胜率为 42.86%
请问如果胜率是 A% (A 是一个两位小数),最少需要参加几局游戏(至少需要参加一局游戏)。

输入描述:

一个两位小数 , 表示A

输出描述:

输出一个自然数,表示最少参加了几局游戏。

思路

枚举分母,从2-10000

AC代码

#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+7;
const int INF=0x3f3f3f3f;
typedef long long ll;

int main(){
    double a;
    cin>>a;
    ll ans=0;
    if(a==0||a==1)
        {
        cout<<1<<endl;
        return 0;
    }
    for(int i=2;i<=10000;i++){
        double num=a*i/100;
        int num1;
        int res=num*10;
        if(res%10>=5){
            num1=num+1;
        }else{
            num1=num;
        }
        int t=1.0*num1/i*10000;
        if((int)(1.0*num1/i*100000)%10>=5){
            t++;
        }
        int a1=a*100;
        if(t==a1){
            ans=i;
            break;
        }
    }
    cout<<ans<<endl;

    return 0;
}

F:隔板与水槽

题目描述

给定一个数轴,数轴上有n个隔板,第i个隔板的高度为a[i],在数轴上的位置为i。
定义一个水槽为两个隔板以及中间的区域,水槽的容积为两个隔板的高度中较小的值乘以两个隔板的距离。
现在你需要找出三个隔板,使得其构成两个水槽(位于中间的隔板将被共用),使得两个水槽的容积和最大,求此容积和。

输入描述:

第一行输入一个整数n。接下来一行输入n个数,表示a[i] 。

输出描述:

一行一个整数,表示三个隔板所组成两个水槽的最大容积和。

思路

三个隔板分别记为i、j、k,先预处理出隔板i到隔板j的容积,和隔板j到隔板k的最大容积(k取j+1——n),枚举隔板i到隔板j的所有情况,求隔板i到隔板j容积加隔板j到隔板k的最大容积和

AC代码

#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+7;
const int INF=0x3f3f3f3f;
typedef long long ll;

int main(){
    int n;
    scanf("%d",&n);
    ll a[n+1];
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    ll d[n+5][n+5];
    ll md[n+5];
    for(int i=1;i<n;i++){
        md[i]=0;
        for(int j=i+1;j<=n;j++){
            d[i][j]=min(a[i],a[j])*(j-i);
            if(d[i][j]>md[i]){
                md[i]=d[i][j];
            }
        }
    }
    ll ans=0;
    for(int i=1;i<n-1;i++){
        for(int j=i+1;j<n;j++){
            ans=max(ans,d[i][j]+md[j]);
        }
    }
    printf("%lld\n",ans);

    return 0;
}

H:取石子

题目描述

Alice和Bob轮流在一个石子堆取石子,谁先无法操作谁输。Alice先手。
给定两个正整数a,b。Alice每次能拿走 a2x2 +ax+1 个石子,Bob每次能拿走b2x2 +by+1 个石子。(x、y是由Alice、Bob自己确定的非负整数,每次的x可以不同,每次的y可以不同,但是每次取走的石子数不能超过总石子数。)
现在有T组询问,每组询问给定a,b,这个石子堆的石子数n,问在两人都足够聪明的前提下,谁能取得胜利。

输入描述:

第一行一个正整数T,表示有几个石子堆。
接下来的T行,每行三个正整数a,b,n。(a,b意义如题目描述,n为这个石子堆的石子数)

输出描述:

输出T行,每行输出一个字符串。如果Alice取得胜利,则输出“Alice”;如果Bob取得胜利,则输出“Bob”。(不包括引号)

思路

Alice和Bob每次都只能取走奇数个石子,所以只需要判断n的奇偶性就可以了,基数Alice赢,偶数Bob赢

AC代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t,a,b,n;
    cin>>t;
    while(t--)
    {
        cin>>a>>b>>n;
        if(n%2==1) cout<<"Alice\n";
        else cout<<"Bob\n";
    }
}

M:让二追三

题目描述

你也想像杭闪打出让二追三的操作,于是打开守望先锋,进行了n场比赛。我们定义“让二追三”为,连续五场比赛为“输输赢赢赢”。你的每场比赛获胜的概率是p(p=a/b),你想知道在n场比赛里你能打出的“让二追三”在模1e9+7下的期望次数。
简单来说,有一个长度为n的01串,其中每一位是1的概率是p(p=a/b),是0的概率是1−p。问这个01串中00111 这个子段在模1e9+7下的期望个数。

输入描述:

第一行一个正整数T,表示有T组数据。
接下来的T行,每行三个正整数a,b,n。(a/b表示一场比赛赢的概率,n表示比赛的场数。)

输出描述:

输出T行,每行输出一个整数,表示在模1e9+7下的00111的期望个数。

思路

运用逆元对分母取模,一个00111子串的概率是(1-p)2 p3,乘以n-4

AC代码

#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+7;
const int INF=0x3f3f3f3f;
typedef long long ll;

const ll M=1e9+7;

inline ll qpow(ll a,ll n,ll p){
    ll ans=1;
    while(n){
        if(n&1){
            ans=ans%p*a%p;
        }
        a=a%p*a%p;
        n>>=1;
    }
    return ans;
}

inline ll inv(ll a,ll p){
    return qpow(a,p-2,p);
}

void solve(){
    int a,b,n;
    cin>>a>>b>>n;
    if(n<5){
        cout<<0<<endl;
        return ;
    }
    ll ans=1;
    ans=(qpow(b-a, 2, M)*qpow(a,3,M)%M*(n-4)%M*inv(qpow(b,5,M),M))%M;
    cout<<ans<<endl;
}

int main(){
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    
    return 0;
}