1、前言

  正式开始的第一周的任务——把NOIP2010至NOIP2015的所有D1/2的T2/3写出暴力。共22题。

  暴力顾名思义,用简单粗暴的方式解题,不以正常的思路思考。能够较好的保证正确性,但是最大的问题在于效率。搞OI这么久,每次考试也经常纠结于暴力与正解之间,其实这两者概念上本来就没有明显的界限,是一组相对概念。

  下面尽可能的不提到正解,但是如果正解容易到我都能够轻松秒的话就还是说一下了。

  普通的DFS/BFS搜索是暴力,但暴力不局限于此。根据向总的话,记忆化搜索亦属于暴力,名字逼格这么高分数肯定也高一些。什么是记忆化搜索呢?

  记忆化搜索就是把我们之前搜索过的状态保存下来,在之后搜索再遇到这种状态时就可以避免重复搜索,直接调用上次搜索的结果即可。记忆化搜索适用于重复子结构较多的题目。

  这样看上去貌似好熟悉。。。是啊很像动态规划。。。

  我姑且把它理解为以DFS的形式来实现的动态规划吧,,,虽然向总始终说他不是动态规划。

Tips:(我写的/暴力最佳方式/正解)

2、NOIP2010

② tourist 乌龟棋(?/记忆化搜索/动态规划)

思路:30分暴力直接强行DFS跑所有情况不多说了。考虑本题有一个特别的地方——重叠子结构很多,经常可能出现使用卡片个数相同但是顺序不同的情况。如果直接DFS的话,会浪费大量时间。由于总状态比较少,4张卡片每张只有至多40张,故可以把所有状态存入一个四维数组,f[a][b][c][d]表示在剩下a张1,b张2,c张3,d张4时可以获得的最大分数。在DFS时如果遇到之前已经遇到过的状态,进行比对,选取较大值转移。这样可以省去大量时间,也就是所谓的记忆化搜索。然而一旦你把f[a][b][c][d]的状态转移方程写出来就会发现。。和动态规划有什么区别呢。

代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #define MAXN 355
  4. #define MAXM 45
  5.  
  6. int n, m, w[MAXN], x, t[], f[MAXM][MAXM][MAXM][MAXM];
  7.  
  8. int max(int a, int b) {
  9. return a > b ? a : b;
  10. }
  11.  
  12. int DFS(int o, int a, int b, int c, int d) {
  13. if (f[a][b][c][d] != -) return f[a][b][c][d];
  14. f[a][b][c][d] = ;
  15. if (a) f[a][b][c][d] = max(DFS(o + , a - , b, c, d), f[a][b][c][d]);
  16. if (b) f[a][b][c][d] = max(DFS(o + , a, b - , c, d), f[a][b][c][d]);
  17. if (c) f[a][b][c][d] = max(DFS(o + , a, b, c - , d), f[a][b][c][d]);
  18. if (d) f[a][b][c][d] = max(DFS(o + , a, b, c, d - ), f[a][b][c][d]);
  19. f[a][b][c][d] += w[o];
  20. return f[a][b][c][d];
  21. }
  22.  
  23. int main() {
  24. freopen("tortoise.in", "r", stdin);
  25. freopen("tortoise.out", "w", stdout);
  26. scanf("%d %d", &n, &m);
  27. for (int i = ; i <= n; i++) scanf("%d", &w[i]);
  28. for (int i = ; i <= m; i++) scanf("%d", &x), t[x]++;
  29. memset(f, -, sizeof(f));
  30. printf("%d", DFS(, t[], t[], t[], t[]));
  31. return ;
  32. }

④ water 引水入城(?/BFS+枚举/BFS+动态规划)

思路:对于30分,题目明确是不能满足要求。。(我竟然没意识到这个的重要性)

3、NOIP2011

② hotel 选择客栈(动态规划/枚举+前缀和/搜索+优化??)

代码:

  1. #include <cstdio>
  2. #define MAXN 200005
  3. #define MAXK 65
  4.  
  5. int n, k, p, s, c, v, a[MAXN], f[MAXK][MAXN];
  6.  
  7. int main() {
  8. freopen("hotel.in", "r", stdin);
  9. freopen("hotel.out", "w", stdout);
  10. scanf("%d %d %d", &n, &k, &p);
  11. for (int i = ; i <= n; i++) {
  12. scanf("%d %d", &c, &v);
  13. for (int j = ; j < k; j++) f[j][i] = f[j][i - ] + (j == c);
  14. s += (v <= p ? f[c][a[i] = i] - : f[c][a[i] = a[i - ]]);
  15. }
  16. printf("%d\n", s);
  17. return ;
  18. }

③ mayan Mayan游戏(搜索/搜索/搜索)

思路:太长不写。恶心死了。

⑤ qc 聪明的质检员(?/二分答案/二分答案)

思路:

代码:

⑥ bus 观光公交(?/最短路/贪心或网络流)

思路:

代码:

4、NOIP2012

② game 国王游戏(贪心/贪心/贪心)

思路:这个贪心到底是如何证明的还是不清楚啊,以前做过所以知道怎么贪心。但是我还是耿直的写了直接根据一只手来贪心50分。感觉题目好鬼。对了记得写高精度。

50分代码:

  1. #include <cstdio>
  2. #include <algorithm>
  3. using namespace std;
  4.  
  5. #define MAXN 1005
  6.  
  7. typedef long long ll;
  8.  
  9. #ifdef WIN32
  10. #define lld "%I64d"
  11. #else
  12. #define lld "%lld"
  13. #endif
  14.  
  15. ll n, x0, y0, o, ans;
  16.  
  17. struct Mst {
  18. ll x, y;
  19. } a[MAXN];
  20.  
  21. struct Cmp {
  22. bool operator () (Mst a, Mst b) {
  23. return a.y < b.y;
  24. }
  25. } x;
  26.  
  27. int main() {
  28. freopen("game.in", "r", stdin);
  29. freopen("game.out", "w", stdout);
  30. scanf(lld lld lld, &n, &x0, &y0), o = x0;
  31. for (int i = ; i <= n; i++) scanf(lld lld, &a[i].x, &a[i].y);
  32. sort(a + , a + n + , x);
  33. for (int i = ; i <= n; i++) ans = max(ans, o / a[i].y), o *= a[i].x;
  34. printf(lld, ans);
  35. return ;
  36. }

③ drive 开车旅行(?/枚举/倍增+set)

思路:就枚举吧。

⑤ classroom 借教室(线段树/线段树/二分答案+差分)

思路:30分模拟。可以很明显的看出来线段树是很适合这道题的,只要常数不是很大,100分到手(我也不知道怎么才会把常数写大)。

代码:

  1. #include <cstdio>
  2. #define MAXN 1000005
  3.  
  4. int n, m, c[MAXN], d[MAXN], x[MAXN], y[MAXN], get;
  5.  
  6. struct Tree {
  7. int v, f;
  8. } t[MAXN * ];
  9.  
  10. int min(int a, int b) {
  11. return a < b ? a : b;
  12. }
  13.  
  14. void build(int o, int l, int r) {
  15. if (l == r) {
  16. t[o].v = c[l];
  17. return;
  18. }
  19. int mid = (l + r) >> ;
  20. build(o << , l, mid), build(o << | , mid + , r);
  21. t[o].v = min(t[o << ].v, t[o << | ].v);
  22. }
  23.  
  24. void pushDown(int o) {
  25. t[o << ].v -= t[o].f, t[o << | ].v -= t[o].f;
  26. t[o << ].f += t[o].f, t[o << | ].f += t[o].f;
  27. t[o].f = ;
  28. }
  29.  
  30. void dec(int o, int l, int r, int ql, int qr, int v) {
  31. if (get) return;
  32. if (t[o].f) pushDown(o);
  33. if (l == ql && r == qr) {
  34. t[o].v -= v, t[o].f += v;
  35. if (t[o].v < ) get = ;
  36. return;
  37. }
  38. int mid = (l + r) >> ;
  39. if (qr <= mid) dec(o << , l, mid, ql, qr, v);
  40. else if (ql >= mid + ) dec(o << | , mid + , r, ql, qr, v);
  41. else dec(o << , l, mid, ql, mid, v), dec(o << | , mid + , r, mid + , qr, v);
  42. t[o].v = min(t[o << ].v, t[o << | ].v);
  43. }
  44.  
  45. int main() {
  46. freopen("classroom.in", "r", stdin);
  47. freopen("classroom.out", "w", stdout);
  48. scanf("%d %d", &n, &m);
  49. for (int i = ; i <= n; i++) scanf("%d", &c[i]);
  50. build(, , n);
  51. for (int i = ; i <= m; i++) {
  52. scanf("%d %d %d", &d[i], &x[i], &y[i]);
  53. dec(, , n, x[i], y[i], d[i]);
  54. if (get) {
  55. printf("-1\n%d", i);
  56. return ;
  57. }
  58. }
  59. printf("");
  60. return ;
  61. }

⑥ blockade 疫情控制(枚举/枚举/二分答案+贪心+倍增)

思路:20分枚举。

代码:

  1. #include <cstdio>
  2. #include <algorithm>
  3. using namespace std;
  4.  
  5. #define MAXN 10005
  6.  
  7. int n, u, v, w, m, a[MAXN];
  8. int o, h[MAXN], vis[MAXN], res, b[MAXN], c[MAXN], btot, ctot;
  9.  
  10. struct Edge {
  11. int v, next, w;
  12. } e[MAXN];
  13.  
  14. void addEdge(int u, int v, int w) {
  15. o++, e[o] = (Edge) {v, h[u], w}, h[u] = o;
  16. }
  17.  
  18. void DFS(int o, int fa) {
  19. for (int x = h[o]; x; x = e[x].next) {
  20. int v = e[x].v;
  21. if (v == fa) continue;
  22. if (a[v]) res += a[v];
  23. DFS(v, o);
  24. }
  25. }
  26.  
  27. int work() {
  28. for (int x = h[]; x; x = e[x].next) {
  29. int v = e[x].v;
  30. res = a[v], DFS(v, );
  31. if (!res) b[++btot] = e[x].w;
  32. else if (res != ) c[++ctot] = e[x].w * (res - );
  33. }
  34. sort(b + , b + btot + ), sort(c + , c + ctot + );
  35. return b[] + c[ctot];
  36. }
  37.  
  38. int main() {
  39. freopen("blockade.in", "r", stdin);
  40. freopen("blockade.out", "w", stdout);
  41. scanf("%d", &n);
  42. for (int i = ; i <= n - ; i++)
  43. scanf("%d %d %d", &u, &v, &w), addEdge(u, v, w), addEdge(v, u, w);
  44. scanf("%d", &m);
  45. for (int i = ; i <= m; i++) scanf("%d", &o), a[o]++;
  46. printf("%d", work());
  47. return ;
  48. }

5、NOIP2013

② match 火柴排队(树状数组+逆序对/枚举/树状数组或归并排序+逆序对)

思路:考虑给出的式子在什么情况下可以获得最小值?两列数组分别最大对最大,次大对次大……最小对最小。为了达到这一局面,求逆序对就行了!(就行了。哦。)这个点确实考的非常偏啊,如果没有提前看过的话怎么做?

这个插下逆序对的概念:

对于一个包含N个非负整数的数组A[1..n],如果有i < j,且A[i] > A[j],则称(A[i] , A[j])为数组A中的一个逆序对。

代码:

  1. #include <cstdio>
  2. #include <algorithm>
  3.  
  4. #define MAXN 100005
  5. #define MOD 99999997
  6. using namespace std;
  7.  
  8. int n, a[MAXN], b[MAXN], ta[MAXN], tb[MAXN], c[MAXN], ans, tot[MAXN];
  9.  
  10. struct cmpa {
  11. bool operator () (int a,int b) {
  12. return (ta[a]<ta[b]);
  13. }
  14. } xa;
  15.  
  16. struct cmpb {
  17. bool operator () (int a, int b) {
  18. return (tb[a] < tb[b]);
  19. }
  20. } xb;
  21.  
  22. int lowbit(int o) {
  23. return o & -o;
  24. }
  25.  
  26. void update(int o) {
  27. while (o <= n) tot[o]++, o += lowbit(o);
  28. }
  29.  
  30. int getSum(int o) {
  31. int ans = ;
  32. while (o) ans += tot[o], o -= lowbit(o);
  33. return ans;
  34. }
  35.  
  36. int main() {
  37. freopen("match.in", "r", stdin);
  38. freopen("match.out", "w", stdout);
  39. scanf("%d", &n);
  40. for (int i = ; i <= n; i++) scanf("%d", &ta[i]), a[i] = i;
  41. for (int i = ; i <= n; i++) scanf("%d", &tb[i]), b[i] = i;
  42. sort(a + , a + n + , xa), sort(b + , b + n + , xb);
  43. for (int i = ; i <= n; i++) c[b[i]] = a[i];
  44. for (int i = ; i <= n; i++) update(c[i]), (ans += (i - getSum(c[i]))) %= MOD;
  45. printf("%d", ans);
  46. return ;
  47. }

③ truck 货车运输(最大生成树/SPFA+优化/最大生成树+倍增)

思路:30分算法直接SPFA维护最长路,我用的30分是Kruskal维护最大生成树,一条边一条边加进去进行判断。。。然而这道题做到60分的暴力也不难——就是把这两种30分算法综合一下(what...)。当且仅当所选择的边在最大生成树上的时候,可以得到最优解。故可以事先求出最大生成树,在最大生成树上进行SPFA!蠢的想不到啊卧槽。100分的话,感觉不是很难吧暂时没写,最大生成树+树上倍增LCA。

30分代码:

  1. #include <cstdio>
  2. #include <algorithm>
  3.  
  4. #define MAXN 10005
  5. #define MAXM 50005
  6. #define INF 1 << 30
  7.  
  8. using namespace std;
  9.  
  10. int n, u, v, w, q, o;
  11. int s, t, set[MAXN], m;
  12.  
  13. struct Edge {
  14. int u, v, w;
  15. };
  16.  
  17. Edge e[MAXN * ];
  18.  
  19. struct Cmp {
  20. bool operator () (Edge a, Edge b) {
  21. return (a.w > b.w);
  22. }
  23. } x;
  24.  
  25. void addEdge(int u, int v, int w) {
  26. o++, e[o] = (Edge) {u, v, w};
  27. }
  28.  
  29. int check(int x) {
  30. return (set[x] == x ? x : set[x] = check(set[x]));
  31. }
  32.  
  33. int work() {
  34. int ans, get = ;
  35. for (int i = ; i <= m; i++) {
  36. if (check(s) == check(t)) {
  37. get = ;
  38. break;
  39. }
  40. int c1 = check(e[i].u), c2 = check(e[i].v);
  41. if (c1 != c2) set[c1] = c2, ans = e[i].w;
  42. }
  43. return get ? ans : -;
  44. }
  45.  
  46. int main() {
  47. freopen("truck.in", "r", stdin);
  48. freopen("truck.out", "w", stdout);
  49. scanf("%d %d", &n, &m);
  50. for (int i = ; i <= m; i++) scanf("%d %d %d", &u, &v, &w), addEdge(u, v, w);
  51. sort(e + , e + m + , x);
  52. scanf("%d", &q);
  53. while (q--) {
  54. scanf("%d %d", &s, &t);
  55. for (int i = ; i <= n; i++) set[i] = i;
  56. printf("%d\n", work());
  57. }
  58. return ;
  59. }

60分代码:

  1. #include <cstdio>
  2. #include <string>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. #define MAXN 10005
  7. #define MAXM 50005
  8. #define INF 1 << 30
  9.  
  10. struct Tmp {
  11. int u, v, w;
  12. } te[MAXM];
  13.  
  14. struct Edge {
  15. int v, next, w;
  16. } e[MAXN];
  17.  
  18. struct Cmp {
  19. bool operator () (Tmp a, Tmp b) {
  20. return a.w > b.w;
  21. }
  22. } x;
  23.  
  24. int n, m, t, u, v, w, o, head[MAXN], vis[MAXN], dis[MAXN], q[MAXN * ], set[MAXN];
  25.  
  26. int check(int o) {
  27. return o == set[o] ? o : set[o] = check(set[o]);
  28. }
  29.  
  30. void addEdge(int u, int v, int w) {
  31. o++, e[o] = (Edge) {v, head[u], w}, head[u] = o;
  32. }
  33.  
  34. int SPFA(int x, int y) {
  35. int h = , t = ;
  36. memset(vis, , sizeof(vis)), memset(dis, -, sizeof(dis));
  37. q[] = x, vis[x] = , dis[x] = INF;
  38. while (h != t) {
  39. int o = q[h];
  40. for (int x = head[o]; x; x = e[x].next) {
  41. int v = e[x].v;
  42. if (dis[v] < min(dis[o], e[x].w)) {
  43. dis[v] = min(dis[o], e[x].w);
  44. if (!vis[v]) vis[v] = , q[t] = v, t++;
  45. }
  46. }
  47. vis[o] = , h++;
  48. }
  49. return dis[y];
  50. }
  51.  
  52. int main() {
  53. freopen("truck.in", "r", stdin);
  54. freopen("truck.out", "w", stdout);
  55. scanf("%d %d", &n, &m);
  56. for (int i = ; i <= m; i++) {
  57. scanf("%d %d %d", &u, &v, &w);
  58. te[i] = (Tmp) {u, v, w};
  59. }
  60. sort(te + , te + m + , x);
  61. for (int i = ; i <= n; i++) set[i] = i;
  62. for (int i = ; i <= m; i++) {
  63. int u = te[i].u, v = te[i].v, w = te[i].w;
  64. int c1 = check(u), c2 = check(v);
  65. if (c1 != c2) set[c1] = c2, addEdge(u, v, w), addEdge(v, u, w);
  66. }
  67. scanf("%d", &t);
  68. for (int i = ; i <= t; i++) scanf("%d %d", &u, &v), printf("%d\n", SPFA(u, v));
  69. return ;
  70. }

⑤ flower 花匠(贪心/贪心/动态规划+优化)

思路:最想吐槽的一道题,。为什么正解会想到动态规划。。不是说不可做,这摆明了的可以贪心啊!虽然两年前甚至是一年前都无法很快的想到,但是一年之后的我把这道题当做新题再看一次的时候,实在是想不通为什么要去动态规划的路线。。所以我写了一个代码量极短的贪心。

代码:

  1. #include <cstdio>
  2. #define MAXN 100005
  3.  
  4. int n, h[MAXN], t[], o;
  5.  
  6. int max(int a, int b) {
  7. return a > b ? a : b;
  8. }
  9.  
  10. int main() {
  11. freopen("flower.in", "r", stdin);
  12. freopen("flower.out", "w", stdout);
  13. scanf("%d", &n);
  14. for (int i = ; i <= n; i++) scanf("%d", &h[i]);
  15. for (int j = ; j <= ; j++, o = j)
  16. for (int i = ; i <= n; i++)
  17. if (o ? (h[i] > h[i - ]) : (h[i] < h[i - ])) o ^= , t[o]++;
  18. printf("%d", max(t[], t[]) + );
  19. return ;
  20. }

⑥ puzzle 华容道(BFS+少量优化?/BFS/BFS+SPFA)

思路:直接写了BFS,据说是60分,但是最后得了70分。

70分代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #define MAXN 35
  4.  
  5. const int vx[] = {, , , -}, vy[] = {, -, , };
  6.  
  7. int n, m, t, a[MAXN][MAXN], vis[MAXN][MAXN][MAXN][MAXN];
  8. int ex, ey, sx, sy, tx, ty;
  9.  
  10. struct Queue {
  11. int x, y, ox, oy, d;
  12. } q[MAXN * MAXN * MAXN * MAXN];
  13.  
  14. int BFS() {
  15. int h = , t = ;
  16. q[] = (Queue) {ex, ey, sx, sy, };
  17. while (h != t) {
  18. for (int i = ; i <= ; i++) {
  19. int nx = q[h].x + vx[i], ny = q[h].y + vy[i];
  20. if (nx == q[h].ox && ny == q[h].oy) {
  21. q[t].ox = q[h].x, q[t].oy = q[h].y;
  22. if (q[t].ox == tx && q[t].oy == ty) return q[h].d + ;
  23. }
  24. else q[t].ox = q[h].ox, q[t].oy = q[h].oy;
  25. if (!a[nx][ny] || vis[nx][ny][q[t].ox][q[t].oy]) continue;
  26. vis[nx][ny][q[t].ox][q[t].oy] = ;
  27. q[t].x = nx, q[t].y = ny, q[t].d = q[h].d + ;
  28. t++;
  29. }
  30. h++;
  31. }
  32. return -;
  33. }
  34.  
  35. int main() {
  36. freopen("puzzle.in", "r", stdin);
  37. freopen("puzzle.out", "w", stdout);
  38. scanf("%d %d %d", &n, &m, &t);
  39. for (int i = ; i <= n; i++)
  40. for (int j = ; j <= m; j++) scanf("%d", &a[i][j]);
  41. for (int i = ; i <= t; i++) {
  42. memset(vis, , sizeof(vis));
  43. scanf("%d %d %d %d %d %d", &ex, &ey, &sx, &sy, &tx, &ty);
  44. vis[ex][ey][sx][sy] = ;
  45. printf("%d\n", sx == tx && sy == ty ? :BFS());
  46. }
  47. return ;
  48. }

6、NOIP2014

② link 联合权值(BFS/BFS/树形动态规划)

思路:现在来看还是NOIP2014的题最良心。。。直接根据点与点之间的关系找出所有距离为2的点对,最后再统计权值即可。记得开long long。

代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. #define MAXN 200005
  7. #define MOD 10007
  8.  
  9. #ifdef WIN32
  10. #define lld "%I64d"
  11. #else
  12. #define lld "%lld"
  13. #endif
  14.  
  15. typedef long long ll;
  16.  
  17. ll h[MAXN], w[MAXN], tot[MAXN], n, u, v, o, ans, maxv;
  18.  
  19. struct edge {
  20. ll v, next;
  21. } e[MAXN * ];
  22.  
  23. void add(ll u, ll v) {
  24. o++, e[o] = (edge) {v, h[u]}, h[u] = o;
  25. }
  26.  
  27. void work(ll x, ll fa) {
  28. ll sonv = , tmax = , vmax;
  29. for (ll o = h[x]; o; o = e[o].next) {
  30. ll v = e[o].v;
  31. sonv += w[v];
  32. if (tmax < w[v]) tmax = w[v], vmax = v;
  33. }
  34. for (ll o = h[x]; o; o = e[o].next) {
  35. ll v = e[o].v;
  36. if (v == fa) continue;
  37. if (v != vmax) maxv = max(maxv, tmax * w[v]);
  38. tot[v] += w[fa] + sonv - w[v], work(v, x);
  39. maxv = max(maxv, w[v] * w[fa]);
  40. }
  41. }
  42.  
  43. int main() {
  44. freopen("link.in", "r", stdin);
  45. freopen("link.out", "w", stdout);
  46. scanf(lld, &n);
  47. for (ll i = ; i < n; i++) scanf(lld " " lld, &u, &v), add(u, v), add(v, u);
  48. for (ll i = ; i <= n; i++) scanf(lld, &w[i]);
  49. work(, );
  50. for (ll i = ; i <= n; i++) (ans += w[i] * tot[i]) %= MOD;
  51. printf(lld " " lld, maxv, ans);
  52. return ;
  53. }

③ bird 飞扬的小鸟(动态规划/记忆化搜索/动态规划)

思路:这个题搜索分高的有点过分啊(当然我也是受益者之一)。其实题目本身没有太多难度,无论是搜索还是记忆化搜索还是动态规划,最要注意的部分就是上界的特判。

代码:

  1. #include <cstdio>
  2.  
  3. #define MAXN 10005
  4. #define MAXM 1005
  5. #define INF 0x3f3f3f3f
  6.  
  7. int n, m, k, x[MAXN], y[MAXN], u[MAXN], d[MAXN], f[MAXN][MAXM], ans = INF, cnt;
  8.  
  9. int min(int a, int b) {
  10. return a < b ? a : b;
  11. }
  12.  
  13. int main() {
  14. freopen("bird.in", "r", stdin);
  15. freopen("bird.out", "w", stdout);
  16. scanf("%d %d %d", &n, &m, &k);
  17. for (int i = ; i < n; i++) scanf("%d %d", &x[i], &y[i]);
  18. for (int i = ; i <= n; i++) u[i] = m + ;
  19. for (int i = ; i <= k; i++) {
  20. int o;
  21. scanf("%d", &o), scanf("%d %d", &d[o], &u[o]);
  22. }
  23. for (int i = ; i <= n; i++) {
  24. for (int j = ; j <= m; j++) {
  25. f[i][j] = INF;
  26. if (j > x[i - ]) f[i][j] = min(f[i][j], min(f[i - ][j - x[i - ]], f[i][j - x[i - ]]) + );
  27. }
  28. for (int j = m - x[i - ]; j <= m; j++) f[i][m] = min(f[i][m], min(f[i - ][j], f[i][j]) + );
  29. for (int j = d[i] + ; j <= u[i] - ; j++)
  30. if (j + y[i - ] <= m) f[i][j] = min(f[i][j], f[i - ][j + y[i - ]]);
  31. for (int j = ; j <= d[i]; j++) f[i][j] = INF;
  32. for (int j = u[i]; j <= m; j++) f[i][j] = INF;
  33. int get = ;
  34. for (int j = ; j <= m ; j++)
  35. if (f[i][j] != INF) {
  36. get = ;
  37. break;
  38. }
  39. if (!get) {
  40. printf("0\n%d", cnt);
  41. return ;
  42. }
  43. else if (u[i] != m + ) cnt++;
  44. }
  45. for (int i = ; i <= m; i++) ans = min(ans, f[n][i]);
  46. printf("1\n%d", ans);
  47. return ;
  48. }

⑤ road 寻找道路(搜索/搜索/搜索)

思路:来自day2的水题。正序逆序各对图进行一次扫描,用DFS/BFS/SPFA均可。

代码:

  1. #include <cstdio>
  2. #include <cstring>
  3.  
  4. #define MAXN 10005
  5. #define MAXM 200005
  6. #define INF 0x3f3f3f3f
  7.  
  8. int n, m, u, v, st, en, head[][MAXN], o[], dep[MAXN], vis[MAXN];
  9.  
  10. struct edge {
  11. int v, next;
  12. } e[][MAXM];
  13.  
  14. void add(int u, int v, int x) {
  15. o[x]++, e[x][o[x]] = (edge) {v, head[x][u]}, head[x][u] = o[x];
  16. }
  17.  
  18. void init() {
  19. freopen("road.in", "r", stdin);
  20. freopen("road.out", "w", stdout);
  21. scanf("%d %d", &n, &m);
  22. for (int i = ; i <= m; i++) scanf("%d %d", &u, &v), add(u, v, ), add(v, u, );
  23. scanf("%d %d", &st, &en);
  24. memset(dep, INF, sizeof(dep));
  25. }
  26.  
  27. void BFS1() {
  28. int q[MAXN], h = , t = ;
  29. q[] = en, vis[en] = ;
  30. while (h != t) {
  31. int o = q[h];
  32. for (int x = head[][o]; x; x = e[][x].next) {
  33. int v = e[][x].v;
  34. if (vis[v]) continue;
  35. vis[v] = , q[t] = v, t++;
  36. }
  37. h++;
  38. }
  39. }
  40.  
  41. void BFS2() {
  42. int q[MAXN], h = , t = ;
  43. q[] = st, dep[st] = ;
  44. while (h != t) {
  45. int o = q[h], no = ;
  46. for (int x = head[][o]; x; x = e[][x].next) {
  47. int v = e[][x].v;
  48. if (!vis[v]) {
  49. no = ;
  50. break;
  51. }
  52. }
  53. if (!no)
  54. for (int x = head[][o]; x; x = e[][x].next) {
  55. int v = e[][x].v;
  56. if (dep[v] > dep[q[h]] + ) q[t] = v, t++, dep[v] = dep[q[h]] + ;
  57. }
  58. h++;
  59. }
  60. }
  61.  
  62. int main() {
  63. init(), BFS1(), BFS2();
  64. if (dep[en] != INF) printf("%d", dep[en]); else printf("-1");
  65. return ;
  66. }

⑥ equation 解方程(搜索/搜索/搜索+Hash+取模)

思路:30分从头搜到尾。。。50分是高精度吧,没时间写就没有写了。据说搜索+取模可以省去高精度直接AC?现在应该不是研究这个的时候了。。。我只写了30分的。

30分代码:

  1. #include <cstdio>
  2. #define MAXN 105
  3.  
  4. int n, m, a[MAXN], tot = , ans[MAXN];
  5.  
  6. int main() {
  7. freopen("equation.in", "r", stdin);
  8. freopen("equation.out", "w", stdout);
  9. scanf("%d %d", &n, &m);
  10. for (int i = ; i <= n; i++) scanf("%d", &a[i]);
  11. for (int i = ; i <= m; i++) {
  12. int x = , o = ;
  13. for (int j = ; j <= n; j++) o += a[j] * x, x *= i;
  14. if (o == ) ans[tot++] = i;
  15. }
  16. printf("%d\n", tot);
  17. for (int i = ; i < tot; i++) printf("%d\n", ans[i]);
  18. return ;
  19. }

7、NOIP2015

呵呵哒。你敢信我对这一年的题目什么印象都没有。。他们在那里讲信息传递的时候我一脸懵逼。确实一点都不想回忆这个,所以15年的我一道题都没有去做。

② message 信息传递

③ landlords 斗地主

⑤ substring 子串

⑥ transport 运输计划

NOIP2010-2015后四题汇总的更多相关文章

  1. [题解+总结]NOIP2010-2015后四题汇总

    1.前言 正式开始的第一周的任务--把NOIP2010至NOIP2015的所有D1/2的T2/3写出暴力.共22题. 暴力顾名思义,用简单粗暴的方式解题,不以正常的思路思考.能够较好的保证正确性,但是 ...

  2. NOIP2010~2017部分真题总结

    NOIP2010~2017部分真题总结 2010 (吐槽)md这个时候的联赛还只有4题吗? 引水入城 只要发现对于有合法解的地图,每个蓄水厂贡献一段区间这个结论就很好做了 那么\(O(n^3)\)对每 ...

  3. NOIP2010提高组真题部分整理(没有关押罪犯)

    目录 \(NOIP2010\)提高组真题部分整理 \(T1\)机器翻译: 题目背景: 题目描述: 输入输出格式: 输入输出样例: 说明: 题解: 代码: \(T2\)乌龟棋 题目背景: 题目描述: 输 ...

  4. NOIP模拟题汇总(加厚版)

    \(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...

  5. 退役II次后做题记录

    退役II次后做题记录 感觉没啥好更的,咕. atcoder1219 历史研究 回滚莫队. [六省联考2017]组合数问题 我是傻逼 按照组合意义等价于\(nk\)个物品,选的物品\(\mod k\) ...

  6. Java-集合(没做出来)第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列。 例如: List list = new ArrayList(); list.add(“Hello”); list.add(“World”); list.add(“Learn”); //此时list 为Hello World Learn reverseL

    没做出来 第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列. 例如: List list = new ArrayList(); list.a ...

  7. Dynamic CRM 2015学习笔记 系列汇总

    这里列出所有 Dynamic CRM 2015学习笔记 系列文章,方便大家查阅.有任何建议.意见.需要,欢迎大家提交评论一起讨论. 本文原文地址:Dynamic CRM 2015学习笔记 系列汇总 一 ...

  8. 经典算法题每日演练——第十四题 Prim算法

    原文:经典算法题每日演练--第十四题 Prim算法 图论在数据结构中是非常有趣而复杂的,作为web码农的我,在实际开发中一直没有找到它的使用场景,不像树那样的频繁使用,不过还是准备 仔细的把图论全部过 ...

  9. NOIP2010-普及组复赛-第四题-三国游戏

    题目描述 Description 小涵很喜欢电脑游戏,这些天他正在玩一个叫做<三国>的游戏.  在游戏中,小涵和计算机各执一方,组建各自的军队进行对战.游戏中共有 N 位武将(N为偶数且不 ...

随机推荐

  1. 微信小程序---scroll-view在苹果手机上触底或触顶页面闪动问题

    在项目开发中遇到一个关于scroll-view的的问题,具体如下: 项目要求是横向滚动,由于直接在scroll-view组件设置display:flex不生效,因此考虑直接在scroll-view下增 ...

  2. Web全景图的原理及实现

    全景图的基本原理 全景图是一种广角图.通过全景播放器可以让观看者身临其境地进入到全景图所记录的场景中去.比如像是这个.这种看起来很高大上的效果其实背后的原理并不复杂. 通常标准的全景图是一张2:1的图 ...

  3. CSS中水平居中设置的几种方式

    1.行内元素: 如果被设置元素为文本.图片等行内元素时,水平居中是通过给父元素设置 text-align:center 来实现的. <body> <div class="t ...

  4. 王者荣耀交流协会--第2次Scrum会议

    Scrum master:袁玥 要求1:工作照片 要求2:时间跨度:2017年10月14号  6:02--6:43  共计41min 要求3:地点:一食堂二楼两张桌子旁(靠近卖方便面那边) 要求4:立 ...

  5. 冲刺ing-7

    第七次Scrum冲刺 队员完成的任务 队员 完成任务 吴伟华 Leangoo的看板截图,燃尽图 蔺皓雯 编写博客 蔡晨旸 进行测试 曾茜 界面设计 鲁婧楠 界面前后端 杨池宇 界面前后端 项目的发布说 ...

  6. c# 画image

    这是一个例子,从数据库中读取然后赋伪彩,生成bitmap,给到imagebox控件(其image属性为平铺). https://pan.baidu.com/s/1hf_fGFHjGoDK_gywuhg ...

  7. mysql 查询数据库或某张表有多大(字节)

    转载:https://www.cnblogs.com/diandiandidi/p/5582309.html 1.要查询表所占的容量,就是把表的数据和索引加起来就可以了 select sum(DATA ...

  8. BETA阶段第一天

    1.提供当天站立式会议照片一张 2.每个人的工作 今天完成工作 林一心 服务器调试 张杭镖 数据库调整 赵意 前端设计 江鹭涛 前端设计 3.发布项目燃尽图 4.每日每人总结 林一心:服务器端的配置不 ...

  9. 陈爽 软件工程导论week2.1

    软件工程导论week2.1 第一章概论问题:1.程序=算法+数据结构  软件=程序+软件工程软件工程的目标是创造足够好的软件,可以从用户满意度,可靠性,软件流程的质量,可维护性等方面判断,但是我们没有 ...

  10. app测试更多机型系统解决方法

    手头上测试机有限,不可能每个机型每个系统都 有一部手机,此时寻求一个什么都有的测试平台就显得尤为重要了. 作为小白的我刚刚使用了一波腾讯优测,简单粗暴有效给力,而且新注册认证用户还有60min免费使用 ...