A. Diagonal Walking

题意

将一个序列中所有的\('RU'\)或者\('UR'\)替换成\('D'\),问最终得到的序列最短长度为多少。

思路

贪心

Code

  1. #include <bits/stdc++.h>
  2. #define F(i, a, b) for (int i = (a); i < (b); ++i)
  3. #define F2(i, a, b) for (int i = (a); i <= (b); ++i)
  4. #define dF(i, a, b) for (int i = (a); i > (b); --i)
  5. #define dF2(i, a, b) for (int i = (a); i >= (b); --i)
  6. #define maxn 110
  7. using namespace std;
  8. char s[maxn];
  9. typedef long long LL;
  10. int main() {
  11. int n, cnt=0;
  12. scanf("%d%s", &n, s);
  13. bool used=0;
  14. F(i, 1, n) {
  15. if (!used && ((s[i]=='U'&&s[i-1]=='R') || (s[i]=='R'&&s[i-1]=='U'))) {
  16. ++cnt, used = true;
  17. }
  18. else used = false;
  19. }
  20. printf("%d\n", n-cnt);
  21. return 0;
  22. }

B. String Typing

题意

要得到一个字符串,有两种操作:

  1. 打印一个字符
  2. 将前面打印过的部分拷贝一遍跟在后面;

    第二种方法最多只能使用一次

问要打印一个字符串最少的操作次数。

思路

数据量暴力可过,但是还是拿来回忆了下后缀数组。

题目即是要求最长的\(A\),使得原字符串\(S\)可表示为\(AAB\)的形式。

通过后缀数组的\(height\)数组,可以知道原串与每一个后缀的\(LCP\)长度,要能够拷贝,满足的条件是:

  1. 该后缀与原串的\(LCP\)长度\(\geq\)两者之间的起始位置差
  2. 该后缀与原串间的起始位置差\(*2\leq\)原串的长度

在所有满足条件的当中取个最大值即可。

Code

  1. #include <bits/stdc++.h>
  2. #define F(i, a, b) for (int i = (a); i < (b); ++i)
  3. #define F2(i, a, b) for (int i = (a); i <= (b); ++i)
  4. #define dF(i, a, b) for (int i = (a); i > (b); --i)
  5. #define dF2(i, a, b) for (int i = (a); i >= (b); --i)
  6. #define maxn 1010
  7. using namespace std;
  8. int wa[maxn], wb[maxn], wv[maxn], wt[maxn], h[maxn], rk[maxn], sa[maxn], n, m, tot, r[maxn];
  9. char s[maxn];
  10. bool cmp(int* r, int a, int b, int l) { return r[a] == r[b] && r[a+l] == r[b+l]; }
  11. void init(int* r, int* sa, int n, int m) {
  12. int* x=wa, *y=wb, *t, i, j, p;
  13. for (i = 0; i < m; ++i) wt[i] = 0;
  14. for (i = 0; i < n; ++i) ++wt[x[i] = r[i]];
  15. for (i = 1; i < m; ++i) wt[i] += wt[i - 1];
  16. for (i = n-1; i >= 0; --i) sa[--wt[x[i]]] = i;
  17. for (j = 1, p = 1; p < n; j <<= 1, m = p) {
  18. for (p = 0, i = n-j; i < n; ++i) y[p++] = i;
  19. for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
  20. for (i = 0; i < n; ++i) wv[i] = x[y[i]];
  21. for (i = 0; i < m; ++i) wt[i] = 0;
  22. for (i = 0; i < n; ++i) ++wt[wv[i]];
  23. for (i = 1; i < m; ++i) wt[i] += wt[i - 1];
  24. for (i = n-1; i >= 0; --i) sa[--wt[wv[i]]] = y[i];
  25. t = x, x = y, y = t, x[sa[0]] = 0;
  26. for (p = 1, i = 1; i < n; ++i) x[sa[i]] = cmp(y, sa[i], sa[i-1], j) ? p - 1 : p++;
  27. }
  28. for (i = 0; i < n; ++i) rk[sa[i]] = i;
  29. int k = 0;
  30. for (i = 0; i < n - 1; h[rk[i++]] = k) {
  31. for (k = k ? --k : 0, j = sa[rk[i] - 1]; r[i+k] == r[j+k]; ++k);
  32. }
  33. }
  34. int main() {
  35. scanf("%d%s", &n, s);
  36. F(i, 0, n) m = max(r[tot++]=s[i], m); r[tot++] = 0;
  37. init(r, sa, tot, ++m);
  38. int p = rk[0], maxx = 0;
  39. dF2(i, p-1, 1) {
  40. if (h[i+1]>=sa[i] && (sa[i]<<1)<=n) maxx = max(maxx, sa[i]);
  41. h[i] = min(h[i], h[i+1]);
  42. }
  43. F(i, p+1, tot) {
  44. if (h[i]>=sa[i] && (sa[i]<<1)<=n) maxx = max(maxx, sa[i]);
  45. h[i+1] = min(h[i], h[i+1]);
  46. }
  47. printf("%d\n", maxx?n-maxx+1:n);
  48. return 0;
  49. }

C. Matrix Walk

题意

一个\(N\times M\)的方格纸,从左到右从上到下分别标号\(1,2,\ldots,N\times M\). 在每一个格子中只能向上下左右相邻的四个格子走。

现给出一个行走序列,要求给出一组合法的\(N,M\). 或者指出不存在。

思路

注意到,合法的序列差只可能为\(1\)或者定值\(M\).

在满足该条件的基础上,还要注意不能从最右边的格子\(+1\),不能从最左边的格子\(-1\).

注意一些细节即可。

Code

  1. #include <bits/stdc++.h>
  2. #define F(i, a, b) for (int i = (a); i < (b); ++i)
  3. #define F2(i, a, b) for (int i = (a); i <= (b); ++i)
  4. #define dF(i, a, b) for (int i = (a); i > (b); --i)
  5. #define dF2(i, a, b) for (int i = (a); i >= (b); --i)
  6. #define maxn 200010
  7. using namespace std;
  8. typedef long long LL;
  9. int a[maxn];
  10. int main() {
  11. int n, y;
  12. scanf("%d", &n);
  13. F(i, 0, n) scanf("%d", &a[i]);
  14. F(i, 1, n) {
  15. y = abs(a[i]-a[i-1]);
  16. if (y==0) { puts("NO"); return 0; }
  17. if (y>1) break;
  18. }
  19. if (y==1) { puts("YES"); printf("%d %d\n", 1, 1000000000); }
  20. else {
  21. F(i, 1, n) {
  22. if (a[i]-a[i-1]==1) {
  23. if (a[i-1]%y==0) { puts("NO"); return 0; }
  24. }
  25. else if (a[i]-a[i-1]==-1) {
  26. if (a[i]%y==0) { puts("NO"); return 0; }
  27. }
  28. else if (abs(a[i]-a[i-1])!=y) { puts("NO"); return 0; }
  29. }
  30. puts("YES");
  31. printf("%d %d\n", 1000000000, y);
  32. }
  33. return 0;
  34. }

D. Fight Against Traffic

题意

给定一张图和起点\(s\)终点\(t\),现在原图不相邻的两点之间加一条边,问有多少种加边方式会不导致\(s\)到\(t\)之间的距离缩短。

思路

若加边导致距离缩短,则必经过刚加的边,假设加的边为\((u,v)\),原\(s,t\)的距离为\(d\),图中所有顶点到\(s\)的最短路距离为\(dist1[]\),到\(t\)的最短路距离为\(dist2[]\)则必有$$dist1[u]+1+dist2[v]\lt d$$或者

\[dist1[v]+1+dist2[u]\lt d
\]

枚举边根据上述条件\(check\)即可。

Code

  1. #include <bits/stdc++.h>
  2. #define F(i, a, b) for (int i = (a); i < (b); ++i)
  3. #define F2(i, a, b) for (int i = (a); i <= (b); ++i)
  4. #define dF(i, a, b) for (int i = (a); i > (b); --i)
  5. #define dF2(i, a, b) for (int i = (a); i >= (b); --i)
  6. #define maxn 1010
  7. struct Edge { int to, ne; }edge[maxn<<1];
  8. int tot, ne[maxn], dist1[maxn], dist2[maxn];
  9. bool vis[maxn], mp[maxn][maxn];
  10. void add(int u, int v) {
  11. edge[tot] = {v, ne[u]};
  12. ne[u] = tot++;
  13. }
  14. struct node {
  15. int v, c;
  16. bool operator < (const node& nd) const { return c > nd.c; }
  17. };
  18. using namespace std;
  19. typedef long long LL;
  20. void dij(int src, int* dist) {
  21. memset(vis, 0, sizeof vis);
  22. memset(dist, 0x3f, maxn*sizeof(int));
  23. vis[src] = true; dist[src] = 0;
  24. priority_queue<node> q;
  25. while (true) {
  26. for (int i = ne[src]; ~i; i = edge[i].ne) {
  27. int v = edge[i].to;
  28. if (vis[v]) continue;
  29. if (dist[src]+1<dist[v]) {
  30. dist[v] = dist[src]+1;
  31. q.push({v, dist[v]});
  32. }
  33. }
  34. while (!q.empty() && vis[q.top().v]) q.pop();
  35. if (q.empty()) break;
  36. vis[src=q.top().v] = true;
  37. }
  38. }
  39. int main() {
  40. memset(ne, -1, sizeof ne);
  41. int n, m, s, t, u, v;
  42. scanf("%d%d%d%d", &n, &m, &s, &t);
  43. F(i, 0, m) {
  44. scanf("%d%d", &u, &v);
  45. add(u, v), add(v, u);
  46. mp[u][v] = mp[v][u] = true;
  47. }
  48. dij(s, dist1);
  49. dij(t, dist2);
  50. int cur = dist1[t], ans = 0;
  51. F2(i, 1, n) {
  52. F2(j, i+1, n) {
  53. if (mp[i][j]) continue;
  54. if (dist1[i]+1+dist2[j]>=cur && dist2[i]+1+dist1[j]>=cur) ++ans;
  55. }
  56. }
  57. printf("%d\n", ans);
  58. return 0;
  59. }

E. Water Taps

题意

\(n\)个水龙头,流量分别为\(a_1,a_2,\ldots,a_n\),温度分别为\(t_1,t_2,\ldots,t_n\),打开若干个水龙头放水,假设放出的水量分别为\(x_1,x_2,\ldots,x_n\),则得到的水温为

\[\frac{\sum_{i=1}^{n}x_it_i}{\sum_{i=1}^{n}x_i}
\]

现要得到温度为\(T\)的水,求能放出的水量的最大值。

思路

因为

\[\frac{\sum_{i=1}^{n}x_it_i}{\sum_{i=1}^{n}x_i}=T
\]

所以

\[\sum_{i=1}^{n}x_i(t_i-T)=0
\]

因此将所有的\(t_i\)减去\(T\)之后,每个水龙头对温度的贡献就分为正贡献和负贡献。

正的放在一边,负的放在一边,因为能取小数,所以少的一边必能取满。

而要多的那边能取到尽量多的\(x\),只要\(t\)尽量小,所以将\(t\)从小到大排序后取即可。

Code

  1. #include <bits/stdc++.h>
  2. #define F(i, a, b) for (int i = (a); i < (b); ++i)
  3. #define F2(i, a, b) for (int i = (a); i <= (b); ++i)
  4. #define dF(i, a, b) for (int i = (a); i > (b); --i)
  5. #define dF2(i, a, b) for (int i = (a); i >= (b); --i)
  6. #define maxn 200010
  7. using namespace std;
  8. typedef long long LL;
  9. struct node {
  10. LL x, t;
  11. bool operator < (const node& nd) const { return t < nd.t; }
  12. }a[maxn];
  13. int main() {
  14. freopen("in.txt", "r", stdin);
  15. freopen("out.txt", "w", stdout);
  16. int n, T;
  17. scanf("%d%d", &n, &T);
  18. F(i, 0, n) scanf("%I64d", &a[i].x);
  19. F(i, 0, n) scanf("%I64d", &a[i].t), a[i].t-=T;
  20. sort(a, a+n);
  21. int p2=0, p1=-1;
  22. double ans=0;
  23. for (; p2<n; ++p2) {
  24. if (a[p2].t<0) p1=p2;
  25. else if (!a[p2].t) ans += a[p2].x;
  26. if (a[p2].t > 0) break;
  27. }
  28. if (p1==-1||p2==n) printf("%.8f\n", ans);
  29. else {
  30. LL sum1=0, sum2=0;
  31. dF2(i, p1, 0) sum1-=a[i].x*a[i].t;
  32. F(i, p2, n) sum2+=a[i].x*a[i].t;
  33. if (sum1>=sum2) {
  34. F(i, p2, n) ans += a[i].x;
  35. int i=p1;
  36. for (; i >= 0; --i) {
  37. if (sum2-a[i].x*(-a[i].t)<0) break;
  38. ans += a[i].x;
  39. sum2 += a[i].x*a[i].t;
  40. }
  41. if (i>=0&&sum2) ans += 1.0*sum2/(-a[i].t);
  42. }
  43. else {
  44. dF2(i, p1, 0) ans += a[i].x;
  45. int i=p2;
  46. for (; i < n; ++i) {
  47. if (sum1-a[i].x*a[i].t<0) break;
  48. ans += a[i].x;
  49. sum1 -= a[i].x*a[i].t;
  50. }
  51. if (i<n&&sum1) ans += 1.0*sum1/a[i].t;
  52. }
  53. printf("%.8f\n", ans);
  54. }
  55. return 0;
  56. }

G. Castle Defense

题意

数轴上\(n\)个位置每个位置放有若干个弓箭手,弓箭手的攻击范围为左右大小为\(r\)的范围内。

一个点的防御程度定义为 该点能被多少个弓箭手攻击到。整条放线的防御程度定义为其上所有点防御程度的 最小值

现可以在防线上增添\(k\)个弓箭手,要求使防线的防御程度最大化,求这个最大值

思路

最小值的最大值,首先显然二分答案。

对于初始固定的弓箭手,一段一段的线段覆盖,可以用前缀和差分来处理。

之后二分答案时的\(check\)怎么进行呢?

用一个变量记录至今为止多放置了多少个弓箭手,从左到右扫

  1. 若位置\(i\)不够,则要在位置\(i+r+1\)补弓箭手
  2. 考虑到位置\(i\)时,要记得消除掉前面的\(i-r-1\)位置的影响

复杂度\(O(n\log n)\)

Code

  1. #include <bits/stdc++.h>
  2. #define F(i, a, b) for (int i = (a); i < (b); ++i)
  3. #define F2(i, a, b) for (int i = (a); i <= (b); ++i)
  4. #define dF(i, a, b) for (int i = (a); i > (b); --i)
  5. #define dF2(i, a, b) for (int i = (a); i >= (b); --i)
  6. #define maxn 500010
  7. using namespace std;
  8. typedef long long LL;
  9. int n, d; LL k;
  10. LL sum[maxn], a[maxn], add[maxn];
  11. bool check(LL x) {
  12. memset(add, 0, sizeof add);
  13. LL temp=0, tot=0;
  14. F2(i, 1, n) {
  15. temp -= (i>=d+2 ? add[i-d-1] : 0);
  16. if (x<=sum[i]+temp) continue;
  17. int p = min(i+d, n);
  18. add[p] = x - (sum[i] + temp);
  19. tot += add[p];
  20. if (tot>k) return false;
  21. temp = x-sum[i];
  22. }
  23. return true;
  24. }
  25. int main() {
  26. scanf("%d%d%I64d", &n, &d, &k);
  27. F2(i, 1, n) {
  28. scanf("%I64d", &a[i]);
  29. int l=max(i-d, 1), r=min(n+1, i+d+1);
  30. sum[l]+=a[i], sum[r]-=a[i];
  31. }
  32. F2(i, 1, n) sum[i] += sum[i-1];
  33. LL l=0, r=2e18, ans;
  34. while (l<=r) {
  35. LL mid=l+r>>1;
  36. if (check(mid)) ans=mid, l=mid+1;
  37. else r=mid-1;
  38. }
  39. printf("%I64d\n", ans);
  40. return 0;
  41. }

Educational Codeforces Round 40 A B C D E G的更多相关文章

  1. Educational Codeforces Round 40 (Rated for Div. 2) 954G G. Castle Defense

    题 OvO http://codeforces.com/contest/954/problem/G 解 二分答案, 对于每个二分的答案值 ANS,判断这个答案是否可行. 记 s 数组为题目中描述的 a ...

  2. Educational Codeforces Round 40 F. Runner's Problem

    Educational Codeforces Round 40 F. Runner's Problem 题意: 给一个$ 3 * m \(的矩阵,问从\)(2,1)$ 出发 走到 \((2,m)\) ...

  3. Educational Codeforces Round 40千名记

    人生第二场codeforces.然而遇上了Education场这种东西 Educational Codeforces Round 40 下午先在家里睡了波觉,起来离开场还有10分钟. 但是突然想起来还 ...

  4. Educational Codeforces Round 40 C. Matrix Walk( 思维)

    Educational Codeforces Round 40 (Rated for Div. 2) C. Matrix Walk time limit per test 1 second memor ...

  5. Educational Codeforces Round 40 (Rated for Div. 2) Solution

    从这里开始 小结 题目列表 Problem A Diagonal Walking Problem B String Typing Problem C Matrix Walk Problem D Fig ...

  6. Educational Codeforces Round 40 I. Yet Another String Matching Problem

    http://codeforces.com/contest/954/problem/I 给你两个串s,p,求上一个串的长度为|p|的所有子串和p的差距是多少,两个串的差距就是每次把一个字符变成另一个字 ...

  7. Educational Codeforces Round 40 G. Castle Defense (二分+滑动数组+greedy)

    G. Castle Defense time limit per test 1.5 seconds memory limit per test 256 megabytes input standard ...

  8. Educational Codeforces Round 40 (Rated for Div. 2)

    A. Diagonal Walking time limit per test 1 second memory limit per test 256 megabytes input standard ...

  9. Educational Codeforces Round 58 A,B,C,D,E,G

    A. Minimum Integer 链接:http://codeforces.com/contest/1101/problem/A 代码: #include<bits/stdc++.h> ...

随机推荐

  1. Fiddler 4 实现手机App的抓包

    Fiddler不但能截获各种浏览器发出的HTTP请求, 也可以截获各种智能手机发出的HTTP/HTTPS请求. Fiddler能捕获IOS设备发出的请求,比如IPhone, IPad, MacBook ...

  2. JMeter学习笔记(九) 参数化3--User Defined Variables

    3.User Defined Variables 1)添加用户定义的变量 2)添加变量 3)添加HTTP请求,引用变量,格式:${} 4)执行HTTP请求,察看结果树 5)用户定义的变量,优缺点: * ...

  3. 51单片机数码管字符H自右向左移动

    #include <reg51.h> #define uint unsigned int #define uchar unsigned char sfr P0M0 = 0x94; sfr ...

  4. CPU拓扑结构

    本篇旨在认识一下以下三种CPU拓扑结构分别是什么: Symmetric multiprocessing (SMP) Non-uniform memory access (NUMA) Simultane ...

  5. 一些排序算法的Python实现

    ''' Created on 2016/12/16 Created by freeol.cn 一些排序算法的Python实现 @author: 拽拽绅士 ''' '''值交换''' def swap( ...

  6. Jquery append()总结(一) 转载

    转载自:http://dushanggaolou.iteye.com/blog/1173457 append(content)  /** * 向每个匹配的元素内部追加内容. * 这个操作与对指定的元素 ...

  7. Python图像全屏显示

    需要在嵌入式设备上全屏显示图像,使用pil显示图像时,只能通过系统的图像浏览器显示.所以使用Python自带的tkinter import Tkinter as tk   这句在Python3中已经改 ...

  8. php静态文件缓存示例

    //开始缓冲区 ob_start(); $cache_file = "./cache/4.3-static.html"; $cache_time = 1; //设置缓存更新时间 i ...

  9. 【版本控制】VisualSVN Server更改SVN版本库存放路径的方法

    最近也玩起了SVN软件版本管理,在本机上安装了VisualSVN Server+TortoiseSVN,感觉还不错吧.但是,版本库存在哪里呢?在安装VisualSVN Server时,已经默认设置了, ...

  10. Mapreduce简要原理与实践

    探索Mapreduce简要原理与实践 目录-探索mapreduce 1.Mapreduce的模型简介与特性?Yarn的作用? 2.mapreduce的工作原理是怎样的? 3.配置Yarn与Mapred ...