传送门

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

j题:

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

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

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

第一种(加点)

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

第二种(增加维度)

  1. 1 #include <iostream>
  2. 2
  3. 3 #include <string.h>
  4. 4
  5. 5 #include <stdio.h>
  6. 6
  7. 7 #include <algorithm>
  8. 8
  9. 9 #include <queue>
  10. 10
  11. 11 #include <vector>
  12. 12
  13. 13 #define ll long long
  14. 14
  15. 15 #define inf 0x3f3f3f3f
  16. 16
  17. 17 #define pii pair<int, int>
  18. 18
  19. 19 const int mod = 1e9+7;
  20. 20
  21. 21 const int maxn = 1e5+7;
  22. 22
  23. 23 using namespace std;
  24. 24
  25. 25 struct node{int to, w, next, cost; } edge[maxn];
  26. 26
  27. 27 int head[maxn], cnt;
  28. 28
  29. 29 int dis[maxn][15], vis[maxn][15];
  30. 30
  31. 31 int n, m, s, t, k;
  32. 32
  33. 33 struct Dijkstra
  34. 34
  35. 35 {
  36. 36
  37. 37 void init()
  38. 38
  39. 39 {
  40. 40
  41. 41 memset(head,-1,sizeof(head));
  42. 42
  43. 43 memset(dis,127,sizeof(dis));
  44. 44
  45. 45 memset(vis,0,sizeof(vis));
  46. 46
  47. 47 cnt = 0;
  48. 48
  49. 49 }
  50. 50
  51. 51
  52. 52
  53. 53 void add(int u,int v,int w)
  54. 54
  55. 55 {
  56. 56
  57. 57 edge[cnt].to = v;
  58. 58
  59. 59 edge[cnt].w = w;
  60. 60
  61. 61 edge[cnt].next = head[u];
  62. 62
  63. 63 head[u] = cnt ++;
  64. 64
  65. 65 }
  66. 66
  67. 67
  68. 68
  69. 69 void dijkstra()
  70. 70
  71. 71 {
  72. 72
  73. 73 priority_queue <pii, vector<pii>, greater<pii> > q;
  74. 74
  75. 75 dis[s][0] = 0;
  76. 76
  77. 77 q.push({0, s});
  78. 78
  79. 79 while(!q.empty())
  80. 80
  81. 81 {
  82. 82
  83. 83 int now = q.top().second; q.pop();
  84. 84
  85. 85 int c = now / n; now %= n;
  86. 86
  87. 87 if(vis[now][c]) continue;
  88. 88
  89. 89 vis[now][c] = 1;
  90. 90
  91. 91 for(int i = head[now]; i != -1; i = edge[i].next)
  92. 92
  93. 93 {
  94. 94
  95. 95 int v = edge[i].to;
  96. 96
  97. 97 if(!vis[v][c] && dis[v][c] > dis[now][c] + edge[i].w)
  98. 98
  99. 99 {
  100. 100
  101. 101 dis[v][c] = dis[now][c] + edge[i].w;
  102. 102
  103. 103 q.push({dis[v][c], v + c * n});
  104. 104
  105. 105 }
  106. 106
  107. 107 }
  108. 108
  109. 109 if(c < k)
  110. 110
  111. 111 {
  112. 112
  113. 113 for(int i = head[now]; i != -1; i = edge[i].next)
  114. 114
  115. 115 {
  116. 116
  117. 117 int v = edge[i].to;
  118. 118
  119. 119 if(!vis[v][c+1] && dis[v][c+1] > dis[now][c])
  120. 120
  121. 121 {
  122. 122
  123. 123 dis[v][c+1] = dis[now][c];
  124. 124
  125. 125 q.push({dis[v][c+1], v + (c + 1) * n});
  126. 126
  127. 127 }
  128. 128
  129. 129 }
  130. 130
  131. 131 }
  132. 132
  133. 133 }
  134. 134
  135. 135 }
  136. 136
  137. 137 }dj;
  138. 138
  139. 139
  140. 140
  141. 141 int main()
  142. 142
  143. 143 {
  144. 144
  145. 145 while(~scanf("%d%d%d%d%d", &n, &m,&s,&t &k))
  146. 146
  147. 147 {
  148. 148
  149. 149 dj.init(); //scanf("%d%d",&s,&t);
  150. 150
  151. 151 while(m--)
  152. 152
  153. 153 {
  154. 154
  155. 155 int u, v, w;
  156. 156
  157. 157 scanf("%d%d%d",&u, &v, &w);
  158. 158
  159. 159 dj.add(u, v, w);
  160. 160
  161. 161 dj.add(v, u, w);
  162. 162
  163. 163 }
  164. 164
  165. 165 dj.dijkstra();
  166. 166
  167. 167 int ans = inf;
  168. 168
  169. 169 for(int i = 0; i <= k; i++)
  170. 170
  171. 171 ans = min(ans, dis[t][i]);
  172. 172
  173. 173 printf("%d\n", ans);
  174. 174
  175. 175 }
  176. 176
  177. 177 }

2019牛客暑期多校训练营(第四场)k题、j题的更多相关文章

  1. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  2. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  3. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  4. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  5. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  6. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

  7. [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem

    链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

  8. 2019牛客暑期多校训练营(第二场)J-Subarray(思维)

    >传送门< 前言 这题我前前后后看了三遍,每次都是把网上相关的博客和通过代码认真看了再思考,然并卵,最后终于第三遍也就是现在终于看懂了,其实懂了之后发现其实没有那么难,但是的的确确需要思维 ...

  9. 2019牛客暑期多校训练营(第一场)-A (单调栈)

    题目链接:https://ac.nowcoder.com/acm/contest/881/A 题意:给定两个长度均为n的数组a和b,求最大的p使得(a1,ap)和(b1,bp)等价,等价的定义为其任意 ...

  10. 2019牛客暑期多校训练营(第一场)A - Equivalent Prefixes(单调栈)

    题意 给定两个$n$个元素的数组$a,b$,它们的前$p$个元素构成的数组是"等价"的,求$p$的最大值."等价"的意思是在其任意一个子区间内的最小值相同. $ ...

随机推荐

  1. 天梯赛练习 L3-016 二叉搜索树的结构 (30分)

    题目分析: 用数型结构先建树,一边输入一边建立,根节点的下标为1,所以左孩子为root*2,右孩子为root*2+1,输入的时候可用cin输入字符串也可用scanf不会超时,判断是否在同一层可以判断两 ...

  2. zabbix_agent items not supported状态

    不记得自己究竟更改了什么东西,然后突然发现所有的有关mysql的监控items都变成了not supported,怎么做不行,最后在web主页把主机删除,又重新添加一下,重新添加了一下模版就好了.这究 ...

  3. 关于SET/GET PARAMETER ID的注意事项

    通常这两个语法配合 PARAMETER, select-options中的参数 memory id来使用. 如,选择屏幕定义 PARAMETER p1 TYPE c LENGTH 10 MEMORY  ...

  4. linux编译模块,包含了头文件却还是报undifind警告

    在编写一个自己写的gadget驱动的时候遇到一个这样的问题,编译的时候报了个警告:WARNING: "usb_composite_register" [-/my_zero.ko] ...

  5. 前端面试准备笔记之JavaScript(04)

    01. DOM的本质 xml是一种可扩展的标记性语言,可扩展就是可以描述任何结构的数据,他是一棵树,可以自定义标签,可以自己扩展. html也是一种特定的xml,他规定了一些标签的名称,结构与xml是 ...

  6. 转 3 jmeter的两种录制方法

      录制1-badboy(推荐) badboy是一款自动化测试工具,它可以完成简单的功能测试和性能测试.其实它是一款独立的测试工具,只不过它录制东西导出的格式适用于jmeter,所以我们经常把jmet ...

  7. b站视频_下载_去水印_视频转mp4-批量下载神器

    b站下载_视频_去水印_转mp4_批量下载的解决办法 以下问题均可解决 b站下载的视频如何保存到本地 b站下载的视频在那个文件夹里 b站下载视频转mp4 b站下载app b站下载在哪 b站下载视频电脑 ...

  8. zabbix客户端监控脚本shell

    zabbix客户端监控脚本shell #!/bin/sh sleep 3 zabbixdir=`pwd` zabbix_version=4.2.5 ###指定版本,最好和server端吻合版本,可以自 ...

  9. 配置《Orange's一个操作系统的实现》环境心得

    <Orange>这本书开篇第一章就做了一个实例,编写了一段引导扇区的代码,但是引导介质仍然采用了已被淘汰多年的软盘.在经历了两天的痛苦查找后终于找到了最方便的解决办法,在此做一下记录,希望 ...

  10. Spring Cloud 2020.0.1 正式发布!真是头疼。。。

    上一篇:Spring Cloud 2020.0.0 正式发布,全新颠覆性版本! 号外!号外!号外! Spring Cloud 2020.0.0 在去年 12 月底,赶在一年的尾巴最后几天仓促发布了,时 ...