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;
}

原文地址:https://www.cnblogs.com/-citywall123/p/11494569.html

时间: 2024-08-25 16:29:14

2019 上半年 南昌网络赛的相关文章

2019 ICPC 南昌网络赛

2019 ICPC 南昌网络赛 比赛时间:2019.9.8 比赛链接:The 2019 Asia Nanchang First Round Online Programming Contest 总结 // 史上排名最高一次,开场不到两小时队友各A一题加水题共四题,排名瞬间升至三四十名 // 然后后三小时就自闭了,一题都没有突破...最后排名211 hhhh ? ? B. Fire-Fighting Hero 题意 队友做的,待补. ? AC代码 #include<cstdio> #includ

2019 ICPC 南昌网络赛 - Subsequence (子串判断,预处理,超时)

?? ?? ?? 题意:一个字符串s,t个字符串p,判断p是不是s的子序列 预处理出对于字符串s,每个位置i之后第一个字母x的位置,匹配子序列的时候就相当于在母串上往后跳,如果跳到母串末尾,子序列还没有结束,匹配失败. 然而!超时了QAQ,只能过八组样例,网上也只能找到过九组的,,,希望有哪位大神路过指点一下了 int tag[33],nxt[MAXN][30]; char s[MAXN],p[MAXN]; void init() { int n=strlen(s); for(int j=0;j

2019 ICPC 南昌网络赛 - Max answer (区间和,区间最值)

?? ???? 题意:价值 = 区间和 × 区间最小值,求数组的子区间的最大价值 (1)区间和---->前缀和 (2)O(n^2) 枚举区间 ---> O( n ) 枚举元素,根据当前元素查询相应区间和 对每个元素,维护他作为最小值的左右端点,枚举数组中的元素,该元素大于0为例,查找( i , r [ i ] )的前缀和最大值,( l [ i ] - 1 , i - 1 )的前缀和最小值,注意这里 l [ i ] -1 可能会小于1 ,ST表应从0开始维护 丧心病狂的压行QWQ ll a[MA

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

ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval 题目大意:给一个长度为n,值域为[1, n]的序列{a},要求支持m次操作: 单点修改 1 pos val 询问子区间中某个值域的数的个数,连续的相同数字只记为一个.(即统计数字段的个数) 2 L R x y 数据范围: 1 ≤ n,m ≤ 2×10^5 1 ≤ a[i] ≤ n 解题思路: 连续重复的数字只记一次.所以考虑将每个数字段除第一个出现外的数字都删去(记为0).在读入操作的时候暴力模拟,同时维护

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

题意:给你一个数组,然后每次有两种操作,操作一是修改数组里的数,操作二是查询区间[ l , r ] 里有多少个子区间满足以下条件:1.子区间内的数全部相同.2.子区间内的数在x到y之间.3.子区间得是不能延伸的. 题目链接:https://nanti.jisuanke.com/t/41356 题解:首先转化问题,设 b[ i ] = a[i]==a[i-1] ? 0 : a[i],然后问题就变成了问询区间内有多少个x到y之间的数.(注意左端点特判)这不就是主席树....带修改...好,树状数组加

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

题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上弄了3小时,思路大体都是对的,但就是没法实现.这几天恶补线段树. 首先可以利用单调栈来查找满足a[i]为最小值的最大区间L[i]~R[i].然后利用线段树求一个段的和sum.最小前缀lsum和最小后缀rsum.然后遍历a[i]: a[i]>0:最优为sum(L[i],R[i])*a[i] a[i]<

2019年ICPC南昌网络赛 J. Distance on the tree 树链剖分+主席树

边权转点权,每次遍历到下一个点,把走个这条边的权值加入主席树中即可. #include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> using namespace std; const int maxx = 2e5+10; struct node{ int l,r,cnt; }tree[maxx*40]; int head[maxx],rk[maxx],siz[maxx

2019南昌网络赛-I. Yukino With Subinterval 线段树套树状数组

TMD...这题卡内存卡的真优秀... 所以以后还是别用主席树的写法...不然怎么死的都不知道... 树套树中,主席树方法开权值线段树...会造成空间的浪费...这道题内存卡的很紧... 由于树套树已经不需要持久化了,直接动态开点就完事了...用主席树方法开过不去,要么超内存,要么越界... 大概思路...这题要求的[L,R]区间内,满足x<=a[i]<=y的连续的段数, 这题大概是个套路题,我们很容易想到,我们把连续的区间变成单点,把一段区间,类似1 1 1 3 5 变成 1 0 0 3 5

19南昌网络赛L

校赛打杂没施展开. 题意:一开始给你一颗 (0,0)到(0,l)的树. 这棵树每一年会长出来三个幼芽(雾),长度均为l/4,方向分别是左转60,右转60,和不变. 年份<=14 考虑3^14直接暴力存边然后考虑每条边贡献.发现奇难无比. 考虑剪枝. 注意到如果一根树枝的被砍掉了那么他所有的孩子全都不算贡献了.妙啊!变成傻逼题. 抄一下板子. 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef double db; 4 c