• 2019 上半年 南昌网络赛


    B、Fire-Fighting Hero

    图论题-单源最短路径:添加一个顶点,连接各个救火团队所在的救火点,路径长度均设为 0,设该顶点为源,即变成了单源最短路径问题。使用两次Dijkstra算法可求出两个最短路径 的最大值。比较时将救火团队的乘以C进行比较可避免分数操作。

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    int vis[1005],way[1005][1005],dis[1005],a[1005];
    int n,m;
    //vis[i]标记已经处理过的点,dis[j]记录起点s到点j最近的距离,way[][]表示路径关系
    void init()
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(i==j)
                    way[i][j]=0;
                else
                    way[i][j]=INF;
            }
        }
    }
    void Dijkstra(int s)
    {
        int mn;
        for (int i = 1; i <= n; i++)//初始化
        {
            vis[i] = 0;
            dis[i] = way[s][i];
        }
        vis[s] = 1;
        for (int i = 1; i <= n; i++)
        {
            int u;
            mn = INF;
            u = -1;
            for (int j = 1; j <= n; j++)//找出离初始起点s直接距离最近的点,记录下标和最近距离
            {
                if (vis[j] == 0 && dis[j] < mn)
                {
                    u = j;
                    mn = dis[j];
                }
            }
            if (u == -1)//如果没有找到
                break;
            vis[u] = 1;
            for (int j = 1; j <= n; j++)//更新
            {
                if (vis[j] == 0)
                {
                    if (dis[u] + way[u][j] < dis[j])
                        dis[j] = dis[u] + way[u][j];
                }
            }
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int s,k,c;
            scanf("%d%d%d%d%d",&n,&m,&s,&k,&c);//n是起火点的个数,m是边数,s是消防英雄所在位置,k个消防队,c是系数
            for(int i=0;i<k;i++)
                scanf("%d",&a[i]);
            init();
            for(int i=0;i<m;i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                if(way[x][y]>z)
                {
                    way[x][y]=z;
                    way[y][x]=z;
                }
            }
            Dijkstra(s);
            int ans1=0;
            for(int i=1;i<=n;i++)//消防英雄到各个起火点距离的最大值
                ans1=max(ans1,dis[i]);
            
            for(int i=0;i<k;i++)//把n个消防队连接起来,变成一个点
            {
                for(int j=0;j<k;j++)
                    way[a[i]][a[j]]=0;
            }
            Dijkstra(a[0]);
            int ans2=0;
            for(int i=1;i<=n;i++)//遍历消防队到各个起火点距离的最大值
                ans2=max(ans2,dis[i]);
        
            if(ans1>ans2*c)
                printf("%d
    ",ans2);
            else
                printf("%d
    ",ans1);
        }
        return 0;
    }

    E、Magic Master

    题意:有n张连续的牌,一次操作m张牌,q次询问,每次询问数字为x的牌在洗牌之前的位置。

    操作是:先把n张牌洗牌之后放在桌面上,每次从桌面拿一张牌到手中,拿完一张牌之后,把桌面上面的m张牌一次放到最底下,重复操作,直到拿完桌面上的所有牌;

    最后手上的牌的顺序是依次递减的

    题解:用队列逆向模拟还原即可:从第n张牌开始,把第n张牌从手里放到桌面之后,把最底下的牌放到最顶上,然后把第n-1张牌放到桌面,再把最底下的牌放到最顶上,直到手里没有牌

    #include<iostream>
    #include<queue>
    using namespace std;
    
    int n,m,t,k;
    int b[40000005];
    int q[40000005];
    int main()
    {
        cin>>t;
        while(t--)
        {
            cin>>n>>m>>k;
            queue<int>p;
            for(int i=0;i<k;i++)
                cin>>q[i];
            for(int i=n;i>=1;i--)
            {
                if(!p.empty())
                {
                    for(int j=1;j<=m;j++)
                    {
                        int top=p.front();
                        p.pop();
                        p.push(top);
                    }
                }
                p.push(i);
            }
            for(int i=n;i>=1;i--)
            {
                int now=p.front();
                b[i]=now;
                p.pop();
            }
        
            for(int i=0;i<k;i++)
                cout<<b[q[i]]<<endl;
        }
    
        return 0;
    }

    H、The Nth Item

    题意:定义一个函数F,输入q(代表q次询问),n(代表给定的第一个值),q次询问只输出最后的结果并对998244353取模

    假设第i次询问的结果是F[ ni ] = temp,那么下一次的n[i+1]=n[i]^(temp*temp);

    输出q次询问的异或和ans=ans^temp;

    #include <iostream>
    #include<string.h>
    #include<stdio.h>
    #include<map>
    #define ll long long
    using namespace std;
    const ll mod = 998244353;
    map<ll,ll>mp;
    struct mat
    {
        ll m[2][2];
        mat()
        {
            memset(m, 0, sizeof(m));
        }
    };
    mat mul(mat &A, mat &B)
    {
        mat C;
        for (int i = 0; i < 2; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                for (int k = 0; k < 2; k++) 
                {
                    C.m[i][j] = (C.m[i][j] + A.m[i][k] * B.m[k][j]) % mod;
                }
            }
        }
        return C;
    }
    mat pow(mat A, ll n)
    {
        mat B;
        B.m[0][0] = B.m[0][1] = 1;
        while (n)
        {
            if (n & 1)
                B = mul(A, B);
            A = mul(A, A);
            n >>= 1;
        }
        return B;
    }
    int main()
    {
        ll n,ans=0,q,temp;
        scanf("%lld%lld",&q,&n);
        while (q--)
        {
            if(mp[n])//如果F[n]已经计算过就直接用
                ans=ans^mp[n];
            else
            {
                if(n<2)
                    temp=n;
                else
                {
                    mat A;
                    A.m[0][0] = 3;
                    A.m[0][1] = 2;
                    A.m[1][0] = 1;
                    mat B = pow(A, n);
                    temp=B.m[1][0];
                }
                ans=ans^temp;
                mp[n]=temp;
            }
            n=n^(temp*temp);
        }
        printf("%lld
    ", ans);
        return 0;
    }
  • 相关阅读:
    阿里巴巴的云原生应用开源探索与实践
    Helm 3 发布 | 云原生生态周报 Vol. 27
    带你上手一款下载超 10 万次的 IDEA 插件
    最强CP!阿里云联手支付宝小程序如何助力双11?
    媲美5G的Wifi网速、“备战”资产一键领……揭秘双11小二背后的保障力量
    dubbo-go 的开发、设计与功能介绍
    饿了么交付中心语言栈转型总结
    数据一致性检测的应用场景与最佳实践
    2684亿!阿里CTO张建锋:不是任何一朵云都撑得住双11
    《DNS稳定保障系列3--快如闪电,域名解析秒级生效》
  • 原文地址:https://www.cnblogs.com/-citywall123/p/11494569.html
Copyright © 2020-2023  润新知