2019 上半年 南昌网络赛

Posted -citywall123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",ans2);
        else
            printf("%d\n",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;

 

以上是关于2019 上半年 南昌网络赛的主要内容,如果未能解决你的问题,请参考以下文章

2019ICPC南昌网络赛总结

2019icpc南昌网络赛

2019南昌网络赛-I(单调栈+线段树)

2019南昌icpc网络赛 I题 分块套BIT

ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval

2019 南昌网络赛icpc I题 cdq分治或分块