zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第四场)k题、j题

    传送门

    k题:

    题意:

    给你一串由数字构成的字符串,你从这个字符串中找子字符串使这个字符串是300的倍数

    题解:

    这道题和第三场的B题极其相似

    首先可以把是三百的倍数分开,必须要是100和3的倍数

    是100的倍数就要求后面必须有两个0

    是3的倍数就可以通过这个子字符串的数字之和是3的倍数来判断

    那么暴力来计算子字符串肯定会超时,所以这个3的倍数这里要优化

    首先我们要对这个字符串进行初始化,计算它的前缀和取余3后的结果

    首先对一个0的出现要特判,因为题目上说了0也算300的倍数

    其次大家想一下如果字符串两个位置取余3后的结果一样(假设结果为2),那么这两个位置中间一段就是3的倍数

    因为我们预处理的是前缀和取余3后的结果,那么如果第一个位置之前取余3后的结果2,后面还有一个位置取余后也是2,那么让这后一个位置的前缀减去前一个位置的前缀,那么不就把这个2给消了吗,因此可以通过这样把复杂度降低

    还有上边只是说了是3的倍数,并没有说是300的倍数,因此还要判断这个位置和前边那个位置是不是0

    上代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=1e5+10;
     7 char str[maxn];
     8 int w[maxn],v[maxn];
     9 int main()
    10 {
    11     scanf("%s",str+1);
    12     int len=strlen(str+1);
    13     int ans=0;
    14     for(int i=1;i<=len;++i)
    15     {
    16         ans=ans+str[i]-'0';
    17         ans%=3;
    18         v[i]=ans;
    19     }
    20     long long sum=0;
    21     for(int i=1;i<=len;++i)
    22     {
    23         if(str[i]=='0')
    24         {
    25             sum++;
    26             if(str[i-1]=='0')
    27             {
    28                 sum+=w[v[i]];
    29             }
    30         }
    31         w[v[i-1]]++; //这一点就是来限制子字符串的个数要大于1,                                                                //因为一个0的已经特判了
    32     }
    33     printf("%lld
    ",sum);
    34     return 0;
    35 }
    View Code

    j题:

    这道题时遇到分层图最短路问题,我原来是想通过记录最短路路径,然后在对这个最短路路径上的最大边剔除,但是一直RE,只好拿出来分层最短路模板了

    分层最短路讲解---->传送门

    我在这里就把他的模板拿过来^_^

    第一种(加点)

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 const int INF=0xffffff;
     8 const int maxn=1e7+10;
     9 int n,m,nnn[maxn],fir[maxn],to[maxn],val[maxn],cnt,dis[maxn],d[maxn],w[maxn],q[maxn];
    10 //int flag[maxn][maxn];
    11 struct shudui1
    12 {
    13     int start,value;
    14     bool operator <(const shudui1 q)const
    15     {
    16         return value>q.value;
    17     }
    18 } str1;
    19 priority_queue<shudui1>r;
    20 void JK()
    21 {
    22     memset(dis,0,sizeof(dis));
    23     while(!r.empty())
    24     {
    25         str1=r.top();
    26         r.pop();
    27         int x=str1.start;
    28         if(dis[x]) continue;
    29         dis[x]=1;
    30         for(int i=fir[x]; i!=-1; i=nnn[i])
    31         {
    32             if(!dis[to[i]] && d[to[i]]>d[x]+val[i])
    33             {
    34                 str1.value=d[to[i]]=d[x]+val[i];
    35                 str1.start=to[i];
    36                 r.push(str1);
    37             }
    38         }
    39     }
    40 }
    41 void init()
    42 {
    43     memset(d,0x3f,sizeof(d));
    44     memset(fir,-1,sizeof(fir));
    45     cnt=0;
    46 }
    47 void add_edge(int x,int y,int z)
    48 {
    49     nnn[++cnt]=fir[x];
    50     fir[x]=cnt;
    51     to[cnt]=y;
    52     val[cnt]=z;
    53 }
    54 int main()
    55 {
    56     int s,t,k;
    57     //memset(path,-1,sizeof(path));
    58     scanf("%d%d%d%d%d",&n,&m,&s,&t,&k);
    59     init();
    60     while(m--)
    61 
    62         {
    63 
    64             int u, v, w;
    65 
    66             scanf("%d%d%d",&u, &v, &w);
    67 
    68             for(int i = 0; i <= k; i++)
    69 
    70             {
    71 
    72                 add_edge(u + i * n, v + i * n, w);
    73 
    74                 add_edge(v + i * n, u + i * n, w);
    75 
    76                 if(i != k)
    77 
    78                 {
    79 
    80                     add_edge(u + i * n, v + (i + 1) * n, 0);
    81 
    82                     add_edge(v + i * n, u + (i + 1) * n, 0);
    83 
    84                 }
    85 
    86             }
    87 
    88         }
    89     str1.start=s;
    90     d[s]=0;
    91     str1.value=0;
    92     r.push(str1);
    93     JK();
    94     int ans=INF;
    95     for(int i = 0; i <= k; i++)
    96         ans = min(ans, d[t + i * n]);
    97     printf("%d
    ",ans);
    98     return 0;
    99 }
    View Code

    第二种(增加维度)

      1 #include <iostream>
      2 
      3 #include <string.h>
      4 
      5 #include <stdio.h>
      6 
      7 #include <algorithm>
      8 
      9 #include <queue>
     10 
     11 #include <vector>
     12 
     13 #define ll long long
     14 
     15 #define inf 0x3f3f3f3f
     16 
     17 #define pii pair<int, int>
     18 
     19 const int mod = 1e9+7;
     20 
     21 const int maxn = 1e5+7;
     22 
     23 using namespace std;
     24 
     25 struct node{int to, w, next, cost; } edge[maxn];
     26 
     27 int head[maxn], cnt;
     28 
     29 int dis[maxn][15], vis[maxn][15];
     30 
     31 int n, m, s, t, k;
     32 
     33 struct Dijkstra
     34 
     35 {
     36 
     37     void init()
     38 
     39     {
     40 
     41         memset(head,-1,sizeof(head));
     42 
     43         memset(dis,127,sizeof(dis));
     44 
     45         memset(vis,0,sizeof(vis));
     46 
     47         cnt = 0;
     48 
     49     }
     50 
     51  
     52 
     53     void add(int u,int v,int w)
     54 
     55     {
     56 
     57         edge[cnt].to = v;
     58 
     59         edge[cnt].w = w;
     60 
     61         edge[cnt].next = head[u];
     62 
     63         head[u] = cnt ++;
     64 
     65     }
     66 
     67  
     68 
     69     void dijkstra()
     70 
     71     {
     72 
     73         priority_queue <pii, vector<pii>, greater<pii> > q;
     74 
     75         dis[s][0] = 0;
     76 
     77         q.push({0, s});
     78 
     79         while(!q.empty())
     80 
     81         {
     82 
     83             int now = q.top().second; q.pop();
     84 
     85             int c = now / n; now %= n;
     86 
     87             if(vis[now][c]) continue;
     88 
     89             vis[now][c] = 1;
     90 
     91             for(int i = head[now]; i != -1; i = edge[i].next)
     92 
     93             {
     94 
     95                 int v = edge[i].to;
     96 
     97                 if(!vis[v][c] && dis[v][c] > dis[now][c] + edge[i].w)
     98 
     99                 {
    100 
    101                     dis[v][c] = dis[now][c] + edge[i].w;
    102 
    103                     q.push({dis[v][c], v + c * n});
    104 
    105                 }
    106 
    107             }
    108 
    109             if(c < k)
    110 
    111             {
    112 
    113                 for(int i = head[now]; i != -1; i = edge[i].next)
    114 
    115                 {
    116 
    117                     int v = edge[i].to;
    118 
    119                     if(!vis[v][c+1] && dis[v][c+1] > dis[now][c])
    120 
    121                     {
    122 
    123                         dis[v][c+1] = dis[now][c];
    124 
    125                         q.push({dis[v][c+1], v + (c + 1) * n});
    126 
    127                     }
    128 
    129                 }
    130 
    131             }
    132 
    133         }
    134 
    135     }
    136 
    137 }dj;
    138 
    139  
    140 
    141 int main()
    142 
    143 {
    144 
    145     while(~scanf("%d%d%d%d%d", &n, &m,&s,&t &k))
    146 
    147     {
    148 
    149         dj.init(); //scanf("%d%d",&s,&t);
    150 
    151         while(m--)
    152 
    153         {
    154 
    155             int u, v, w;
    156 
    157             scanf("%d%d%d",&u, &v, &w);
    158 
    159             dj.add(u, v, w);
    160 
    161             dj.add(v, u, w);
    162 
    163         }
    164 
    165         dj.dijkstra();
    166 
    167         int ans = inf;
    168 
    169         for(int i = 0; i <= k; i++)
    170 
    171             ans = min(ans, dis[t][i]);
    172 
    173         printf("%d
    ", ans);
    174 
    175     }
    176 
    177 }
    View Code
  • 相关阅读:
    深入理解HTTP Session
    java中使用队列:java.util.Queue
    throws/throw Exception 异常应用
    Log4j实现对Java日志的配置全攻略
    java中volatile关键字的含义
    hibernate调用oracle存储过程||函数
    手势仿QQ侧滑---秀清
    归档和解档---秀清
    全局定义UINavigationContoller--By秀清
    重力感应 加速计- By严焕培
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11268087.html
Copyright © 2011-2022 走看看