140pts(100+30+10)Rank3

前几天还考了一场,AK,没什么好总结的,所以就没写博客。

炸:

T2,模拟退火突然不会了,写个状压dp,排序边的时候sort的N而不是M

这个坑经常出!!

T3,打表没有打全,规律推的有问题,本来应该加到5,我却加到了2。

这个注意着点就行了

我的变量名又开始各种鬼畜了。。。

由于教练让我写题解了,所以题解就搁下面了

rainbow

题目大意:笛卡尔坐标系中,x轴非负半轴上有7个在第一象限半圆,你需要把这7个半圆的半径增加一个相同的实数,使得这些半圆恰好覆盖线段\(y=h(0\le x\le x_0)\)

题解:由于答案是单调的(就是如果一个\(r_0\)是合法的答案,那么\(\forall r\ge r_0\)都有\(r\)是一个合法的答案)

所以可以通过二分答案来解决,二分这个\(r\),然后算出所有的圆覆盖直线\(y=h\)的区域(一定是一个线段),然后跑一遍区间求并即可。如果一个圆和线段相离,把这个区间设为\([-1,-1]\)即可(或者是别的奇奇怪怪的值都行)。注意不要计算两个圆之间的交点,不好写,有误差还容易写错

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cmath>
  5. #define six 6
  6. #define seven 7
  7. #define eight 8
  8. #define hexo 1e-9//鬼畜变量名常量名系列程序之Nescafe29
  9. using namespace std;
  10. struct fuck
  11. {
  12. double x, r;
  13. }a[10];
  14. struct pdf
  15. {
  16. double l, r;
  17. }s[10];
  18. double h, x0;
  19. bool ghj1222(const pdf &a, const pdf &b)
  20. {
  21. if (fabs(a.l - b.l) <= hexo)
  22. return a.r < b.r;
  23. return a.l < b.l;
  24. }
  25. bool valid(double ass)
  26. {
  27. //然后就是区间覆盖问题了你特么求交点干什么
  28. //233333
  29. for (int i = 1; i <= seven; i++)
  30. {
  31. double qtmd = (a[i].r + ass) * (a[i].r + ass) - h * h;
  32. if (qtmd <= 0)
  33. s[i].l = s[i].r = 123456789;
  34. else
  35. {
  36. qtmd = sqrt(qtmd);
  37. s[i].l = a[i].x - qtmd;
  38. s[i].r = a[i].x + qtmd;
  39. }
  40. }
  41. sort(s + 1, s + eight, ghj1222);
  42. double l = s[1].l, r = s[1].r;
  43. if (l > 0)
  44. return false;
  45. for (int i = 2; i <= seven; i++)
  46. {
  47. if (r >= x0)
  48. return true;
  49. if (s[i].l <= r)
  50. r = max(s[i].r, r);
  51. else
  52. return false;
  53. }
  54. return r >= x0;
  55. }
  56. int main()
  57. {
  58. freopen("rainbow.in", "r", stdin);
  59. freopen("rainbow.out", "w", stdout);
  60. scanf("%lf%lf", &h, &x0);
  61. for (int i = 1; i <= seven; i++)
  62. scanf("%lf%lf", &a[i].x, &a[i].r);
  63. double l = 0;
  64. double r = 12345;//Very Safe!!!..........2333333qtmd
  65. while (r - l > hexo)
  66. {
  67. double mid = (l + r) / 2;
  68. if (valid(mid))
  69. r = mid;
  70. else
  71. l = mid;
  72. }
  73. printf("%.2f\n", l);
  74. fclose(stdin);
  75. fclose(stdout);
  76. return 0;
  77. }

clover

题目大意:给定一张图,求一个图的分量使得这个分量内所有联通块的点权和为0,且最小化边权。

题解:本题可以随机化、模拟退火做,也可以状压dp

状压dp:由于\(N\le16\)所以可以状压dp做。令\(f[i]\)代表到达状态为i的最小花费,其中\(i\)的二进制第\(j\)位为1,则第\(j\)个点已经被选择,否则未被选择。首先\(f[0]=0\),\(Ans=f[2^N-1]\)。由于是最小化某个数,所以f数组先初始化为极大值。考虑转移:首先一个转移肯定是往原状态里加一个连通块组成一个新状态,所以我们预处理出所有的连通块,保证这个连通块内所有的点和为0,且所有点之间仅由“属于这个连通块的边”联通。我们枚举所有的状态,先判断这个状态表示的点集内所有点权和是否为0,如果为0,那么在这个点集内跑一遍最小生成树。注意先把所有边sort一下,然后只对于起点和终点都属于这个点集内的边更新并查集,否则不去更新。最后处理出来最小生成树要检查一下这个点集内所有的点是否联通(也就是所有的点的父亲是否都是一个节点),如果是就返回最小生成树的边权即可,不是要返回这个转移不合法。记录所有合法的转移(记录点集和花费)。先枚举所有状态,然后枚举所有转移(因为一个状态一定是由一个编号比它小的状态转移过来的),(这里使用填表法)如果这个转移能够由某一个状态转移到这个状态(用二进制xjb判一下就行了)那么就计算出这个状态并转移即可。最后如果答案没有被更新,那么就是Impossible,否则输出答案即可。你也可以预先搜一下是否有解,有解条件是所有强连通分量内点权和都为0

模拟退火:下面是来自GMPotlc的模拟退火算法,请大家认真欣赏一下。

T2 : 正经(xjb)算法

根据题意 如果 x 点是可行的 那么我们只需要 让他们联通即可 那么我们就可以联想到

最小生成树 , 然而事实 总是那么不尽如人意 , duipai 发现 结果几乎全是错的

仔细思考发现 有这样一个 error :

对于 两个 联通块 如果各自联通块的权值和 分别已经 为零了 那么我们就不在需要

去将这两个联通块 连在一起 , 怎么解决这个问题呢 ?

聪明的人 都已经想到了 xjb 算法

我们 对于 克鲁斯卡尔 加边的时候 我们 xjb rand()即可

然后 进行 300000 次即可 (当然更聪明的人 其实可以xjb 退火了)

这是我的状压dp

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <algorithm>
  5. using namespace std;
  6. int N, M, tot, g[20][20], val[20];
  7. //第0位为第1个,第1位为第2个,最高位为第N个
  8. struct edge
  9. {
  10. int u, v, w;
  11. }a[200];
  12. namespace Confusion
  13. {
  14. int st[65600], cost[65600], top, fa[20], f[65600];
  15. int getf(int x)
  16. {
  17. return fa[x] == x ? x : fa[x] = getf(fa[x]);
  18. }
  19. bool cmp(const edge &a, const edge &b)
  20. {
  21. return a.w < b.w;
  22. }
  23. bool valid1(int fuck)
  24. {
  25. int ans = 0;
  26. for (int i = 1; i <= N; i++, fuck >>= 1)
  27. if (fuck & 1)
  28. ans += val[i];
  29. return ans == 0;
  30. }
  31. //表表表表表表表表表表表表表表表表表表表表表
  32. int valid2(int fuck)
  33. {
  34. bool v[20];
  35. memset(v, 0, sizeof(v));
  36. for (int i = 1; i <= N; i++, fuck >>= 1)
  37. if (fuck & 1)
  38. {
  39. v[i] = true;
  40. fa[i] = i;
  41. }
  42. int ans = 0;
  43. //说好的克鲁斯卡尔呢我为什么存的是邻接矩阵??!?!!??!?!?!?!?!?!?!?!?!?
  44. //好了写了个边表
  45. for (int i = 1; i <= M; i++)
  46. {
  47. if (v[a[i].u] == true && v[a[i].v] == true)
  48. {
  49. int x = getf(a[i].u), y = getf(a[i].v);
  50. if (x != y)
  51. {
  52. fa[x] = y;
  53. ans += a[i].w;
  54. }
  55. }
  56. }
  57. int common_father = -1;
  58. for (int i = 1; i <= N; i++)
  59. if (v[i] == true)
  60. {
  61. if (common_father == -1 || getf(i) == common_father)
  62. common_father = getf(i);
  63. else
  64. return -1;
  65. }
  66. return ans;
  67. }
  68. int work()
  69. {
  70. sort (a + 1, a + 1 + M, Confusion::cmp);
  71. tot = (1 << N) - 1;
  72. for (int i = 1; i <= tot; i++)
  73. if (valid1(i))
  74. {
  75. int res = valid2(i);
  76. if (res >= 0)
  77. {
  78. st[++top] = i;
  79. cost[top] = res;
  80. }
  81. }
  82. memset(f, 0x3f, sizeof(f));
  83. f[0] = 0;
  84. for (int i = 1; i <= tot; i++)
  85. {
  86. for (int j = 1; j <= top; j++)
  87. {
  88. if ((i ^ st[j]) + st[j] == i)
  89. f[i] = min(f[i], f[i ^ st[j]] + cost[j]);
  90. }
  91. }
  92. return f[tot];
  93. }
  94. }
  95. namespace Impossible
  96. {
  97. bool v[20];
  98. int search(int x)
  99. {
  100. int ans = val[x];
  101. v[x] = true;
  102. for (int i = 1; i <= N; i++)
  103. if (g[x][i] < 0x3f3f3f3f && v[i] == false)
  104. ans += search(i);
  105. return ans;
  106. }
  107. bool judge()
  108. {
  109. memset(v, 0, sizeof(v));
  110. for (int i = 1; i <= N; i++)
  111. if (v[i] == false)
  112. if (search(i) != 0)
  113. return false;
  114. return true;
  115. }
  116. }
  117. int main()
  118. {
  119. freopen("clover.in", "r", stdin);
  120. freopen("clover.out", "w", stdout);
  121. scanf("%d%d", &N, &M);
  122. for (int i = 1; i <= N; i++)
  123. scanf("%d", &val[i]);
  124. memset(g, 0x3f, sizeof(g));
  125. for (int i = 1; i <= N; i++)
  126. g[i][i] = 0;
  127. for (int x, y, z, i = 1; i <= M; i++)
  128. {
  129. scanf("%d%d%d", &x, &y, &z);
  130. x++;
  131. y++;
  132. a[i] = (edge){x, y, z};
  133. g[x][y] = min(g[x][y], z);
  134. g[y][x] = min(g[y][x], z);
  135. }
  136. if (Impossible::judge() == 0)
  137. puts("Impossible");
  138. else
  139. printf("%d\n", Confusion::work());
  140. fclose(stdin);
  141. fclose(stdout);
  142. return 0;
  143. }

domine

题目大意:询问\(N\)个节点的AVL树的形状数。\(N\le 3000\)。

题解:我们不难想到一个dp的做法:令\(f[i][j]\)代表有i个节点的树的高度为\(j\)的方案数。不难写出转移方程为:

\(\displaystyle f[i][j]=\sum_{x+y=i-1}(f[x][j-1]*f[y][j-1]+f[x][j-2]*f[y][j-1]+f[x][j-1]*f[y][j-2])\)

枚举左子树的节点数为x,右子树的节点数为y,由于整棵树的高度为j,所以一定有一个子树高度为j-1,由于两个子树高度最多差1,所以另一个子树高度可以为j-1或j-2。所以有3种方案:左j-1右j-1,左j-2右j-1,左j-1右j-2。根据乘法原理,整棵树数量为两棵子树的数量相乘,根据加法原理,上面3中方案相加即可。

由于时间复杂度为\(O(n^3)\),所以这里需要稍微优化一下。首先由于树不可能是一个链,我们先假设j枚举到30即可。把f数组打表之后发现j是随着i变化而变化,大概j是i的一个对数函数。每一个i对应存在\(f[i][j]\)长度区间最长为5,且每一个i存在第一个有数的j是i的二进制最高位的位置。所以暴力求i最高位即可,然后向后枚举5位即可。这个能优化到\(O(n^2)\)乘以一个常数,虽然比较慢,但是能卡进去。

还有这道题有一个小坑:题目并没有让你取模\(10^9\)输出,而是保留后9位。就是后9位有前导0也要输出。我们手动模拟发现,当\(n\ge38\)时候有\(Ans\ge10^9\),所以判一下,如果\(n<38\)就直接输出,\(n\ge38\)就要恰好保留9位,保留前导0。如果使用printf函数输出整数就用%09lld%09d即可保留前导0。

另外这题的答案是一个整数数列,在OEIS的编号为A006265,点击超链接即可查看有关信息:N个节点的高度平衡的AVL树的形状。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <iomanip>
  4. #define asshole 1000000000
  5. using namespace std;
  6. //由N个节点组成的高度为M的树的方案数(高度算上根节点)
  7. long long f[3010][3010], ans[3010];
  8. #define N 3000
  9. int highbit(int x)
  10. {
  11. int ans = 0;
  12. while (x > 0)
  13. {
  14. x >>= 1;
  15. ans++;
  16. }
  17. return ans;
  18. }
  19. //orz applepi!!!
  20. //#include <ctime>
  21. int main()
  22. {
  23. // int fuckyou = clock();
  24. // freopen("domine.in", "r", stdin);
  25. // freopen("domine.out", "w", stdout);
  26. f[0][0] = 1;
  27. f[1][1] = 1;
  28. ans[1] = 1;
  29. for (int i = 2; i <= N; i++)
  30. {
  31. int fuck = highbit(i);
  32. for (int j = fuck; j <= fuck + 4; j++)//展现出填表法的威力吧
  33. {
  34. for (int x = 0; x < i; x++)
  35. {
  36. int y = i - 1 - x;
  37. f[i][j] = ((f[i][j] + f[x][j - 1] * f[y][j - 1] % asshole) % asshole + (f[x][j - 2] * f[y][j - 1] % asshole + f[x][j - 1] * f[y][j - 2] % asshole) % asshole) % asshole;
  38. }
  39. (ans[i] += f[i][j]) %= asshole;
  40. }
  41. }
  42. int fuck = 2333;
  43. while (2333)
  44. {
  45. scanf("%d", &fuck);
  46. if (fuck == 0)
  47. break;
  48. if (fuck >= 38)
  49. printf("%09lld\n", ans[fuck]);
  50. else
  51. printf("%lld\n", ans[fuck]);
  52. }//WAWA Lian
  53. // fprintf(stderr, "%d\n", clock() - fuckyou);
  54. fclose(stdin);
  55. fclose(stdout);
  56. return 0;
  57. }

9.27下午考试(Nescafé 29杯模拟赛)的更多相关文章

  1. Nescafe #29 NOIP模拟赛

    Nescafe #29 NOIP模拟赛 不知道这种题发出来算不算侵权...毕竟有的题在$bz$上是权限题,但是在$vijos$似乎又有原题...如果这算是侵权的话请联系我,我会尽快删除,谢谢~ 今天开 ...

  2. 计蒜客蓝桥杯模拟赛 后缀字符串:STL_map+贪心

    问题描述 一天蒜头君得到 n 个字符串 si​,每个字符串的长度都不超过 10. 蒜头君在想,在这 n 个字符串中,以 si​ 为后缀的字符串有多少个呢? 输入格式 第一行输入一个整数 n. 接下来  ...

  3. 2016.10.29 NOIP模拟赛 PM 考试整理

    300分的题,只得了第三题的100分. 题目+数据:链接:http://pan.baidu.com/s/1o7P4YXs 密码:4how T1:这道题目存在着诸多的问题: 1.开始的序列是无法消除的( ...

  4. 【考试总结】欢乐模拟赛_Day2

    \(T1\) 题目描述 在仙界中有着 \(n\) 位神仙, 每位神仙用一个 \(1 ∼ n\) 的特异编号表示, 老祖 \(ChitongZ\) 的编号为 \(1\) . 除去至尊至圣, 统管仙界的老 ...

  5. [SinGuLaRiTy] Nescafe 24杯模拟赛

    [SinGularLaRiTy-1044] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 小水塘(lagoon) 题目描述 忘川沧月的小水塘 ...

  6. 【考试总结】欢乐模拟赛_Day1

    \(T1\) 题目描述 给出一个 \(n × n\) 的, 元素为自然数的矩阵. 这个矩阵有许许多多个子矩阵, 定义它的所有子矩阵形成的集合为 \(S\) . 对于一个矩阵 \(k\) , 定义 \( ...

  7. 计蒜客蓝桥杯模拟赛五J. 程序设计:放置守卫

    在一张 n 行 m 列的方格地图上放置一些守卫,每个守卫能守护上.左.右三个方向上相邻的方格和自己所在的方格.如下图,红色的方格放置守卫,绿色的方格为该守卫守护的区域. 现在要求在地图上放置若干个守卫 ...

  8. 蓝桥杯模拟赛-引爆炸弹-DFS+并查集

    今天整理电脑,翻出来了很久以前大佬给的题,贴一下. 引爆炸弹 1000ms 在一个 n×m的方格地图上,某些方格上放置着炸弹.手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸 ...

  9. 2017-9-10"切题如切菜杯"模拟赛T4 ZZI

    题目 YYH拿到了父亲给的钱欣喜若狂,把这些钱拿来造了n栋房子.现在他要给这些房子通电.他有两种方法:第一种是在房间里搭核电发电机发电,对于不同的房子,他需要花不同的代价Vi:,第二种是将有电的房子i ...

随机推荐

  1. mybatis 学习二 MyBatis简介与配置MyBatis+Spring+MySql

    1.2.2建立MySql数据库 在C:\Program Files\MySQL\MySQL Server 5.7\bin下面: 首先连接MySQL:        mysql  -u root -p ...

  2. jQuery UI vs Kendo UI & jQuery Mobile vs Kendo UI Mobile

    jQuery UI vs Kendo UI http://jqueryuivskendoui.com/#introduction jQuery Mobile vs Kendo UI Mobile ht ...

  3. eclipse中。安装findbugs java检测工具

    问题提出: 当我们编写完代码,做完单元测试等各种测试后就提交正式运行,只能由运行的系统来检测我们代码是否有问题了,代码中隐藏的错误在系统运行的过程中被发现后,然后再来进行相应的修改,那么后期修改的代价 ...

  4. [poj1410]Intersection

    题目大意:求线段与实心矩形是否相交. 解题关键:转化为线段与线段相交的判断. #include<cstdio> #include<cstring> #include<al ...

  5. 2018网络预选赛 徐州G 线段树

    线段树,假设求(x1,y1)点的贡献,就找所有比该点出现时间晚,且x坐标大于x1的点中y最大的,贡献就是Y-y1,由于题目条件限制,不可能有x坐标大于(x1,y1)且y坐标大于y1的点,所以贡献肯定为 ...

  6. iOS 列表三级展开

    效果图如下:        #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDe ...

  7. Python 网络爬虫 007 (编程) 通过网站地图爬取目标站点的所有网页

    通过网站地图爬取目标站点的所有网页 使用的系统:Windows 10 64位 Python 语言版本:Python 2.7.10 V 使用的编程 Python 的集成开发环境:PyCharm 2016 ...

  8. Luogu 3402 可持久化并查集

    点开这题纯属无聊……不过既然写掉了,那就丢一个模板好了 不得不说,可持久化并查集实现真的很暴力,就是把并查集的数组弄一个主席树可持久化. 有一点要注意的是不能写路径压缩,这样跳版本的时候会错,所以弄一 ...

  9. Java中常见设计模式面试

    一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接 ...

  10. Excel课程学习第三课排序与替换

    一.排序 1.简单排序 点到某一个单元格,然后选择排序,就可以按照相应的顺序来排序. 2.自定义排序 按照重要性条件来排序 也可以按照重要性从轻到重挨个排序. 3.按颜色排序 4. 按照中文数字排序, ...