ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

第十五届吉林省大学生程序设计竞赛

2021-12-01 17:32:41  阅读:597  来源: 互联网

标签:吉林省 int res ll long base dy 程序设计 第十五届


最近刚打完吉林省程序设计竞赛,自己比较菜,成绩不是很好,拖累了两位队友,其中一位队友保研,并在比赛前一天拿到了百度的实习offer.另一位是备战考研。

比赛只过了A,B,E,L,M,最终41名

A题:

题目大意:给你一i个数组,判断数组中元素奇数和偶数的个数差是否小于等于1.

签到题

//
// Created by LiuHongzhe on 2021/11/30.
//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
ll ans;
ll x;
ll dx,dy;
int main()
{
    ll i,j,k;
    cin>>n;
    for(i=0;i<n;i++)
    {
        cin>>x;
        if(x%2==0)
            dx++;
        else
        {
            dy++;
        }

    }
    ans=abs(dx-dy);
    if(ans<=1)
    {
        cout<<"Good"<<endl;
    }else
    {
        cout<<"Not Good"<<endl;
    }
    return 0;
}

B题:

题目大意:给三个数a,b,k,计算a/b,保留k位

签到题

//
// Created by LiuHongzhe on 2021/11/30.
//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ll i,j;
    ll a, b,k;
    ll t;
    cin>>a>>b>>k;
    if(a==b)
    {
        cout<<"1.";
        for(i=0;i<k;i++)
        {
            cout<<0;
        }
    } else{
        cout<<"0.";
        for(i=0;i<k-1;i++)
        {
            t=a*10/b;
            cout<<t;
            a=a*10%b;
        }
        ll dt=a*10/b;
        a=a*10%b;
        t=a*10/b;

        if(t>=5&&t<=9)
        {
            cout<<dt+1;
        }
        else
        {
            cout<<dt;
        }
    }
    return 0;
}

E题:

给一个数组,判断是否存在两个元素异或等于1

a[i]^a[j]==1&&i!=j
a[i]^a[j]==1&&i!=j
基础知识:
1^1=0;1^0=1;0^1=1;0^0=0;
若a^b=c则 c^a=(a^b)^a=b
则原题可以推理为是否存在a[i]^1属于数组中的元素

//
// Created by LiuHongzhe on 2021/11/30.
//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll t,n;
ll flag;
int main()
{
    ll i,j;
    ll x;
    cin>>t;
    while(t--)
    {
        set<ll>a;
        flag=false;
        n = 0;
        scanf("%lld", &n);
        for(i=0;i<n;i++)
        {
            scanf("%lld", &x);
            a.insert(x);
        }
        for(auto it:a)
        {
            ll dt=it^1;
            ll dx=a.count(dt);
            if(dx==1)
            {
                flag=true;
                break;
            }
        }
        if(flag)
        {
            printf("Yes\n");
        }else
        {
            printf("No\n");
        }
    }
    return 0;
}

L题:

题目大意:给一个字符串S,定义Si为从S的第i位开始的子串,Si有两种处理办法,一种删去最后一个字符,另一种加入一个字符,最后让Si构造成S的最小次数记位d(Si),求d(Si)中最大的数

//
// Created by LiuHongzhe on 2021/11/30.
//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    int t;
    cin >> t;
    string s;
    while(t--) {
        cin >> s;
        int i;
        const int sz = s.size();
        for(i = 1; i < sz; ++i) {
            if(s[i] == s[i - 1]) continue;
            else break;
        }
        if(i == sz) cout << sz - 1 << endl;
        else cout << sz * 2 - i << endl;
    }
    return 0;
}

M题:

题目大意:给一个数组,求数组的极差与数组长度的乘积。

签到题

//
// Created by LiuHongzhe on 2021/11/30.
//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
ll a[10005];
ll maxn = -100005;
ll minn = 100005;
int main()
{
    cin >> n;
    for(int i = 0; i < n; i++ ){
        cin >> a[i];
        maxn = max(maxn, a[i]);
        minn = min(minn, a[i]);
    }
    ll ans = maxn - minn;
    ans *= n;
    cout << ans << endl;
    return 0;
}

后面题目,比赛中没有做对,比赛结束自己补的,不能保证一定正确

K题:

题目大意:求给定一个长度位2N,括号种类位K的合法的括号数量

对于只有一种括号时,括号的数量是卡特兰数列

对于k种括号时,答案就是卡特兰数列*(k^n)

卡特兰数,应用于:括号化,凸多边形三角划分,给定节点组成二叉搜索树,n对括号正确匹配数目。

此题考查了数学知识:排列组合,快速幂,卡特兰数列

其中排列组合在曾在热身赛中第二题出现过

//
// Created by LiuHongzhe on 2021/11/30.
//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
ll k;
ll N=1e9+7;
ll ans;
ll fastpow1(ll a, ll n) {//快速幂
    ll base = a;
    ll res = 1;
    while(n) {
        if(n & 1)
            res = (base * res) % N;
        base = (base * base) % N;
        n >>= 1;
    }
    return res;
}
ll fun(ll n,ll m)//排列组合
{
    if(m==0)
        return 1;
    ll a[n+5];
    for(int i=1;i<=n;i++)
    {
        a[i]=i;
    }
    for(int j=2;j<=m;j++)
    {
        ll t=j;
        for(int i=n-m+1;i<=n;i++)
        {
            if(__gcd(t,a[i])>1)
            {
                ll dy=__gcd(t,a[i]);
                a[i]=a[i]/dy;
                t=t/dy;
                if(t==1)
                    break;
            }
        }
    }
    ll sum=1;
    for(int i=n-m+1;i<=n;i++)
    {
        sum=(sum*a[i])%N;
    }
    return sum;
}
int main()
{
    cin>>n>>k;
    ll x1= fastpow1(k,n);
    ll x2= fun(2*n,n);
    ll x3=fun(2*n,n-1);
    x3=(x2+N-x3)%N;
    ans=(x3*x1)%N;
    cout<<ans;
    return 0;
}

H题:

根据给出的路径,计算每条边权的期望值,然后求和,结果在用费马小定理处理

费马小定理:

b/a mod p

==>b*a^-1 mod p

==> b*a^p-2 mod p

此代码在处理期望部分可能存在bug,(对于分布期望不会求解。。。。。)

//
// Created by LiuHongzhe on 2021/11/30.
//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,k;
ll x,y,z;
int b[300005];
ll ans;
ll N=998244853;
vector<vector<vector<ll>>>cnt;
ll fastpow1(ll a, ll n) {//快速幂
    ll base = a;
    ll res = 1;
    while(n) {
        if(n & 1)
            res = (base * res) % N;
        base = (base * base) % N;
        n >>= 1;
    }
    return res;
}
void method01(){
    ll i,j;
    for(i=0;i<=n;i++)//打表
    {
        vector<vector<ll>>cnt1;
        for(j=0;j<=i;j++)
        {
            vector<ll>cnt2;
            cnt1.push_back(cnt2);
        }
        cnt.push_back(cnt1);
    }
    ll u,v,w;
    for(i=0;i<m;i++)//数据录入
    {

        cin>>u>>v>>w;
        if(u<v)
            swap(u,v);
        cnt[u][v].push_back(w);
    }
}
void method02(){
    ll i;
    for(i=0;i<k;i++)
    {
        cin>>b[i];
    }
}
void method03(){//求x,y
    ll i,j;
    ll sum=1;
    y=1;
    for(i=k-1;i>0;i--)
    {
        ll dx=b[i];
        ll dy=b[i-1];
        if(dx<dy)
            swap(dx,dy);
        ll len=cnt[dx][dy].size();
        y=(y*len)%N;
        if(len==0)
        {
            cout<<"Stupid Msacywy!"<<endl;
            exit(0);
        }
    }
    x=0;
    for(i=k-1;i>0;i--)
    {
        ll dx=b[i];
        ll dy=b[i-1];
        if(dx<dy)
            swap(dx,dy);
        ll add=0;
        for(j=0;j<cnt[dx][dy].size();j++)
        {
            add=add+cnt[dx][dy][j];
        }
        ll len=cnt[dx][dy].size();
        ll de=(add*sum*y/len)%N;
        x=(x+de)%N;
        sum=(sum*10)%N;
    }
}
void method04(){
    // x/y;
    ll ans=fastpow1(y,N-2);
    ans=(ans*x)%N;
    cout<<ans;
}
int main()
{
    cin>>n>>m>>k;
    method01();
    method02();
    method03();
    method04();
    return 0;
}

C题:

题目大意:给定x0;且xn=(a*x(n-1)+b)%m;是否存在xi是给定的一个数(给定的数<m)

此题涉及线性同余方程求解和BSGS算法

然后自己手动推理了一下公式的转化

 

G题:

题目大意:给一个01矩阵(其中空缺位置为-1)和每行每列的异或值,复原此矩阵。

用到同E题的异或性质,做法类似玩数独游戏,每次对某行或者某列只有一个未知元素的优先处理。既先对处理位置做一个拓扑排序,然后依次处理即可。(但我不会写拓扑排序。。。)

后面补题后更新

下面是官方简要题解和省赛原题

链接:https://pan.baidu.com/s/1e5w2P6tbPSmR-NfazYdXNA 
提取码:uwd9

比赛终榜

第十五届吉林省大学生程序设计竞赛 - 正式赛

标签:吉林省,int,res,ll,long,base,dy,程序设计,第十五届
来源: https://blog.csdn.net/qq_52888009/article/details/121660001

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有