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 上半年 南昌网络赛的主要内容,如果未能解决你的问题,请参考以下文章