信息工程大学第五届超越杯程序设计竞赛(同步赛)vp

本文介绍了五场信息技术竞赛中的编程题目,包括模拟、图论、人员进出管理、路径覆盖和计数问题。提供了对应的代码片段和解决方案策略,展示了参赛者如何运用算法和数据结构解决复杂问题。
摘要由CSDN通过智能技术生成

目录

信息工程大学第五届超越杯程序设计竞赛(同步赛)_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ

A.遗失的旋律

C.财政大臣

D.实验室有多少人

E.在雾中寻宁静

F.不规则的轮回

G.完美数字

M.Monika's game


A.遗失的旋律

思路:模拟即可

代码如下:

#include<bits/stdc++.h>

using namespace std;
#define fs first
#define sc second
#define all(x) x.begin(),x.end()
typedef long long ll;
typedef pair<int,int> PII;

const int mod = 998244353;

int main()
{
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);

    int n,q;
    cin>>n>>q;
    
    string s;
    cin>>s;
    
    while(q--)
    {
        int op;
        cin>>op;
        if(op==1)
        {
            int y;cin>>y;
            s[y-1]^=1;
        }
        else
        {
            int x,l,r;
            cin>>x>>l>>r;
            l--,r--;
            for(int i=l;i<=r;i++)
            {
                if(s[i]=='0')x=(x+1)%mod;
                else x=(2*x)%mod;
            }
            cout<<x<<endl;
        }
    }
    return 0;
}

C.财政大臣

思路:用邻接表来存图,用数组存每个点的money,每次有变动从根结点dfs一下,记录变化值。

代码如下:

#include<bits/stdc++.h>

using namespace std;
#define fs first
#define sc second
#define all(x) x.begin(),x.end()
typedef long long ll;
typedef pair<int,int> PII;

const int N = 1e5+10,M = 2*N;

int e[M],ne[M],h[N],idx;

int n,m;

int v[N];//记录每个城市的money

ll range[N];//变化值

void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

void dfs(int u,int fa)//fa表示父亲,不能向上搜索;s表示当前这个结点的变化量(从根结点向下累加)
{
    range[u]+=range[fa];
    for(int i=h[u];~i;i=ne[i])
    {
        int j=e[i];
        if(j!=fa)dfs(j,u);   
    }
}
void solve()
{
    memset(h,-1,sizeof(h));
    cin>>n>>m;
    for(int i=0;i<n-1;i++)
    {
        int a,b;cin>>a>>b;
        add(a,b),add(b,a);
    }

    for(int i=1;i<=n;i++)
    {
        int x;cin>>x;
        v[i]=x;
    }

    while(m--)
    {
        int op,u,x;
        cin>>op>>u>>x;
        if(op==1)range[u]+=x;
        else range[u]-=x;
    }

    dfs(1,0);

    for(int i=1;i<=n;i++)cout<<v[i]+range[i]<<" ";
}
int main()
{
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);

    solve();
    
    return 0;
}

D.实验室有多少人

思路:用pair维护信息,排序然后遍历即可,1为到达,2为离开

代码如下:

#include<bits/stdc++.h>

using namespace std;
#define fs first
#define sc second
#define all(x) x.begin(),x.end()
typedef long long ll;
typedef pair<int,int> PII;

const int N = 1e6+10;

bool cmp(PII a,PII b)
{
    if(b.fs==a.fs)return a.sc<b.sc;
    return a.fs<b.fs;
}
void solve()
{
    int n;
    cin>>n;
    
    vector<PII> b;
    
    for(int i=0;i<n;i++)
    {
        int st,ed;
        cin>>st>>ed;
        b.push_back({st,1});
        b.push_back({ed,2});
    }
    
    sort(all(b),cmp);
    
    int ans=0,cnt=0;
    for(auto x:b)
    {
        if(x.sc==1)cnt++;
        else cnt--;
        ans=max(ans,cnt);
    }
    
    cout<<ans<<endl;
}
int main()
{
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);

    int t=1;
    
    while(t--)
    {
        solve();
    }
    return 0;
}

E.在雾中寻宁静

思路:正序dfs即可完成覆盖

代码如下:

#include<bits/stdc++.h>

using namespace std;
#define fs first
#define sc second
#define all(x) x.begin(),x.end()
typedef long long ll;
typedef pair<int,int> PII;

const int N = 2e5+10, M = 2*N;

int e[M],ne[M],h[N],idx;

int n,q,col[N];

void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

void dfs(int u,int color)
{
    col[u]=color;
    for(int i=h[u];~i;i=ne[i])
    {
        int j=e[i];
        dfs(j,color);
    }
}
void solve()
{
    memset(h,-1,sizeof(h));
    cin>>n;
    for(int i=1;i<=n-1;i++)
    {
        int x;cin>>x;
        add(x,i+1);
    }

    cin>>q;

    vector<PII> a(q);
    for(int i=0;i<q;i++)
    {
        int x,y;
        cin>>x>>y;
        a[i]={x,y};
    }
    for(int i=0;i<q;i++)
    {
        int x=a[i].fs,y=a[i].sc;
        dfs(x,y);
    }

    for(int i=1;i<=n;i++)cout<<col[i]<<" ";
}
int main()
{
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);

    int t=1;

    while(t--)
    {
        solve();
    }
    return 0;
}

F.不规则的轮回

思路:模拟,O(1)查询

代码如下:

#include<bits/stdc++.h>

using namespace std;
#define fs first
#define sc second
#define all(x) x.begin(),x.end()
typedef long long ll;
typedef pair<int,int> PII;

const int N = 1e4+10;

int a[N][N];

void solve()
{
   int n;
   cin>>n;

   for(int i=0;i<n;i++)
   {
    int x,y;
    cin>>x>>y;
    a[x][y]++;
    while(x!=y)
    {
        if(x>y)x-=y;
        else if(x<y)y-=x;
        a[x][y]++;
    }
   }

   int q;
   cin>>q;

   while(q--)
   {
    int qx,qy;
    cin>>qx>>qy;
    cout<<a[qx][qy]<<endl;
   }
}
int main()
{
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);

    int t=1;
    
    while(t--)
    {
        solve();
    }
    return 0;
}

G.完美数字

思路:考虑10的因子是2和5,也就是两个数字含有2,5因子的乘积可以构成10,那么min(t2,t5)就是10的个数,也就是0的个数.

copy一下好的题解qaq

代码如下:

#include<bits/stdc++.h>

using namespace std;
#define fs first
#define sc second
#define all(x) x.begin(),x.end()
typedef long long ll;
typedef pair<int,int> PII;

const int N = 2e5+10;

int a[N],a2[N],a5[N];

int sum2[N],sum5[N];//遍历区间要用到区间内的因子数量

ll res;

void cal(int x,int i)
{
    int t=x;
    while(t%2==0)t/=2,a2[i]++;
    t=x;
    while(t%5==0)t/=5,a5[i]++;
}
void solve()
{
    int n,k;
    cin>>n>>k;

    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        cal(a[i],i);//统计a[i]中,2和5因子的数量
    }

    for(int i=1;i<=n;i++)
    {
        sum2[i]=sum2[i-1]+a2[i];
        sum5[i]=sum5[i-1]+a5[i];
    }

    for(int l=1;l<=n;l++)
    {
        for(int r=l;r<=n;r++)//一个区间可以有1个数,所以r可以从l开始
        {
            int t2=sum2[r]-sum2[l-1];
            int t5=sum5[r]-sum5[l-1];
            int sum=min(t2,t5);
            if(sum>=k)//如果成立,那么把他后面的数字加上去也成立,所以区间数量为n-r+1
            {
                res+=n-r+1;
                break;
            }
        }
    }
    cout<<res<<endl;
}
int main()
{
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);

    int t=1;

    while(t--)
    {
        solve();
    }
    return 0;
}

M.Monika's game

思路:n*(n-1)/2

代码如下:

#include <bits/stdc++.h>
using namespace std;
int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    long long t, n;
    long long summ;
    
    cin >> t;
    for(int i = 1; i <= t; i++){
        cin >> n;
        summ = n*(n-1)/2;
        printf("%lld\n", summ);
    }

    return 0;
}
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jared_devin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值