A.小Hi和小Ho的礼物

谜之第1题,明明是第1题AC率比C还要低。题目是求在n个不同重量袋子选4袋,2袋给A,2袋给B,使2人获得重量相同,求问方案数。

我也是一脸懵b。。。o(n2)暴力枚举发现把第i行列和第j行列去掉,再求剩下的a[i]+a[j]数就是解

用容斥,要把(i,i)(i,j)(j,i)(j,j)加回来,想o(n3),结果tle

结果发现求结果时只求a[i]+a[j]个数就行了,只需改变跟a[i]+a[j]有关的计数就可以了。

还要有一个计数器,储存每个数字分别有多少个

然后直接计数与a[i]+a[j]相关数据

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<queue>
  5. #include<stack>
  6. #include<math.h>
  7. #include<vector>
  8. #include<map>
  9. #include<set>
  10. #include<stdlib.h>
  11. #include<cmath>
  12. #include<string>
  13. #include<algorithm>
  14. #include<iostream>
  15. using namespace std;
  16. typedef long long ll;
  17.  
  18. int h[];
  19. int a[];
  20. int c[];
  21. int main()
  22. {
  23. int i,n,j,k;
  24. memset(h,,sizeof(h));
  25. memset(c,,sizeof(c));
  26. scanf("%d",&n);
  27. for(i=;i<n;i++)
  28. {
  29. scanf("%d",a+i);
  30. c[a[i]]++;
  31. }
  32. for(i=;i<n;i++)
  33. {
  34. for(j=;j<n;j++)
  35. {
  36. h[a[i]+a[j]]++;
  37. }
  38. }
  39. ll ans=;
  40. for(i=;i<n-;i++)
  41. {
  42. for(j=i+;j<n;j++)
  43. {
  44. if((a[i]+a[j])%==)
  45. h[a[i]+a[j]]-=c[(a[i]+a[j])/];
  46. h[a[i]+a[j]]-=c[a[j]]*;
  47. h[a[i]+a[j]]-=c[a[i]]*;
  48. h[a[i]+a[j]]+=;
  49. h[a[i]+a[i]]+=;
  50. h[a[j]+a[j]]+=;
  51. ans+=h[a[i]+a[j]];
  52. if((a[i]+a[j])%==)
  53. h[a[i]+a[j]]+=c[(a[i]+a[j])/];
  54. h[a[i]+a[j]]+=c[a[j]]*;
  55. h[a[i]+a[j]]+=c[a[i]]*;
  56. h[a[i]+a[j]]-=;
  57. h[a[i]+a[i]]-=;
  58. h[a[j]+a[j]]-=;
  59. }
  60. }
  61. printf("%lld\n",ans/);
  62. return ;
  63. }

B.投掷硬币

意外地很简单。dp一波,dp[n,i]表示银币投n次正好i次向上的概率,然后

dp(n,i)=dp(n-1,i)*(1-p(n))+dp(n-1,i-1)*p(n),解决

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<queue>
  5. #include<stack>
  6. #include<math.h>
  7. #include<vector>
  8. #include<map>
  9. #include<set>
  10. #include<stdlib.h>
  11. #include<cmath>
  12. #include<string>
  13. #include<algorithm>
  14. #include<iostream>
  15. using namespace std;
  16. typedef long long ll;
  17.  
  18. double p[];
  19. double dp[][];
  20. int main()
  21. {
  22. int i,j,m,n;
  23. scanf("%d%d",&n,&m);
  24. for(i=;i<n;i++)
  25. scanf("%lf",p+i);
  26. memset(dp,,sizeof(dp));
  27. int old=,now=;
  28. dp[][]=;
  29. for(i=;i<n;i++)
  30. {
  31. old^=,now^=;
  32. memset(dp[now],,sizeof(dp[now]));
  33. for(j=;j<i+;j++)
  34. {
  35. dp[now][j]+=dp[old][j]*(-p[i]);
  36. dp[now][j+]+=dp[old][j]*p[i];
  37. }
  38. }
  39. printf("%lf\n",dp[now][m]);
  40. return ;
  41. }

C.可疑的记录

题目大意就是求去除某边使n个边的有向无环图变成n-1条边的有向无环图的边编号集合

这里不是判个圈就解决的,不仅要让有向树只有1个0入度点(编号还必须是1),并且所有0出度点只有1个入度

所以判完圈后,还要把标记在圈上的边分别操作,并判断0入度点数和0入度点是不是1号

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<queue>
  5. #include<stack>
  6. #include<math.h>
  7. #include<vector>
  8. #include<map>
  9. #include<set>
  10. #include<stdlib.h>
  11. #include<cmath>
  12. #include<string>
  13. #include<algorithm>
  14. #include<iostream>
  15. using namespace std;
  16.  
  17. const int N =;
  18.  
  19. int head[][N],cnt[]={,};
  20. int to[][N<<],next1[][N<<];
  21. bool isCircle[N<<];
  22. bool vis[N];
  23. bool ans[N];
  24.  
  25. void addedge(int u,int v,int i)
  26. {
  27. to[i][cnt[i]]=v;
  28. next1[i][cnt[i]]=head[i][u];
  29. head[i][u]=cnt[i]++;
  30. }
  31.  
  32. int dfs(int u,int eno)
  33. {
  34. vis[u]=true;
  35. int cn=-;
  36. for(int i=head[][u];i!=-;i=next1[][i])
  37. {
  38. if(i == (eno^))
  39. continue;
  40. int v=to[][i];
  41. if(vis[v])
  42. {
  43. cn=v;
  44. isCircle[i/]=true;
  45. vis[u]=false;
  46. return cn;
  47. }
  48. cn = dfs(v,i);
  49. if(cn!=-)
  50. {
  51. isCircle[i/]=true;
  52. vis[u]=false;
  53. if(cn == u)
  54. return -;
  55.  
  56. return cn;
  57. }
  58. }
  59. vis[u]=false;
  60. return cn;
  61. }
  62.  
  63. int inc[N],ouc[N];
  64. int e[N][];
  65. int main()
  66. {
  67. memset(head,-,sizeof(head));
  68. memset(vis,,sizeof(vis));
  69. memset(isCircle,,sizeof(isCircle));
  70. memset(inc,,sizeof(inc));
  71. memset(ouc,,sizeof(ouc));
  72. memset(ans,,sizeof(ans));
  73. int i,n,u,v;
  74. scanf("%d",&n);
  75. int in0=n;
  76. for(i=;i<n;i++)
  77. {
  78. scanf("%d%d",&u,&v);
  79. u--,v--;
  80. e[i][]=u;
  81. e[i][]=v;
  82. addedge(u,v,);
  83. addedge(u,v,);
  84. addedge(v,u,);
  85. if(inc[v]==)in0--;
  86. ouc[u]++;inc[v]++;
  87. }
  88. dfs(,-);
  89. bool first=true;
  90. for(i=;i<n;i++)
  91. {
  92. if(!isCircle[i])continue;
  93. u=e[i][];
  94. v=e[i][];
  95. ouc[u]--;inc[v]--;
  96. if(inc[v]==)in0++;
  97. if(in0 == && inc[] == )
  98. {
  99. ans[i]=true;
  100. if(!first)putchar(' ');
  101. printf("%d",i+);
  102. first=false;
  103. }
  104. if(inc[v]==)in0--;
  105. ouc[u]++;inc[v]++;
  106. }
  107. putchar('\n');
  108. return ;
  109. }

D.剑刃风暴

虽说最近搞了MVPTree,也是跟查询点有关。。。但是这题没有给确定点,没法搞~~场上没做

题目不能O(n3)(就是两两确定点,再向外探索点确定个数),会超时

看了其他人的代码后才领悟,敢情是极角排序

看下图就知道是怎么回事了。。。点要跟O点距离原点不足R,那么以自身点为中心,R半径的圆与O圆(半径同样为R)相交部分就是原点的可选范围。

再加入一个点,只要对应圆也包含原来可选范围的一部分,这一部分的原点画的圆也能包含新点

就像这样:

红色区域包含3个圆,仔细观察就会发现其实就是蓝色扇形与棕色扇形对应角相交的部分

可以大胆推断,新点与O点相交角包含区域可默认为可选区域

区域包含的角越多,包含的对应点也越多

然后代码就是这样:(场上排第2名的代码,除开排版问题比较容易看懂)

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <algorithm>
  5.  
  6. #define Mn 2005//平面点集中点数
  7.  
  8. using namespace std;
  9.  
  10. const double eps = 1e-;//精度调高点没跑~
  11. const double pi = acos(-1.0);
  12.  
  13. #define sqr(x) ((x) * (x))
  14.  
  15. double R;//定长
  16.  
  17. struct point
  18. {
  19. double x,y;
  20. void read()
  21. {
  22. scanf("%lf%lf",&x,&y);
  23. }
  24.  
  25. void print()
  26. {
  27. printf("%lf%lf\n",x,y);
  28. }
  29.  
  30. double friend dis(const point &a,const point &b)
  31. {
  32. return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
  33. }
  34.  
  35. } p[Mn + ];
  36.  
  37. struct alpha
  38. {
  39.  
  40. double v;
  41. bool flag;
  42. bool friend operator <(const alpha &a,const alpha &b)//排序专用偏序关系
  43. {
  44. return a.v < b.v;
  45. }
  46.  
  47. } alp[Mn * Mn + ]; //C(N,2)*2的可能交点(可能极角)
  48.  
  49. void solve(int n,int r)
  50. {
  51. R = r;//本题内为单位圆
  52. for(int i = ; i < n; i++)
  53. p[i].read();
  54.  
  55. int MAX = ;
  56. for(int i = ; i < n; i++)
  57. {
  58. int t = ;
  59. for(int j = ; j < n; j++)
  60. {
  61. if(i == j)
  62. continue;
  63.  
  64. double theta,phi,D;
  65. D = dis(p[i],p[j]);
  66. if(D > 2.0 * R)//距离超界直接秒杀
  67. continue;
  68.  
  69. //关键部分
  70. theta = atan2(p[j].y - p[i].y,p[j].x - p[i].x);
  71. if(theta < )
  72. theta += * pi;
  73. phi = acos(D / (2.0 * R));
  74. alp[t].v = theta - phi + * pi;
  75. alp[t].flag = true;
  76. alp[t + ].v = theta + phi + * pi;
  77. alp[t + ].flag = false;
  78. t += ;
  79. }
  80.  
  81. sort(alp,alp + t);
  82. int sum = ;
  83. for(int j = ; j < t; j++)
  84. {
  85. if(alp[j].flag)
  86. sum ++;
  87. else
  88. sum --;
  89. if(sum > MAX)
  90. MAX = sum;
  91. }
  92. }
  93. printf("%d\n",MAX + );
  94. }
  95.  
  96. int main()
  97. {
  98. int n,r;
  99. while(~scanf("%d%d",&n,&r))
  100. {
  101. solve(n,r);
  102. }
  103. }

hihocoder [Offer收割]编程练习赛14的更多相关文章

  1. hihocoder [Offer收割]编程练习赛14 剑刃风暴

    题目4 : 剑刃风暴 时间限制:20000ms 单点时限:2000ms 内存限制:256MB 描述 主宰尤涅若拥有一招非常厉害的招式——剑刃风暴,“无论是战士还是法师,都害怕尤涅若的武士刀剑技”. 现 ...

  2. hihocoder [Offer收割]编程练习赛14 可疑的记录

    题目3 : 可疑的记录 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi有一棵N个节点的树,编号1-N,其中1号节点是整棵树的根.他把这棵树的N-1条边记录成N-1 ...

  3. hihocoder [Offer收割]编程练习赛14 投掷硬币

    题目2 : 投掷硬币 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi有一枚神奇的硬币.已知第i次投掷这枚硬币时,正面向上的概率是Pi. 现在小Hi想知道如果总共投 ...

  4. hihocoder [Offer收割]编程练习赛14 小Hi和小Ho的礼物

    题目1 : 小Hi和小Ho的礼物 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 某人有N袋金币,其中第i袋内金币的数量是Ai.现在他决定选出2袋金币送给小Hi,再选2袋 ...

  5. hihocoder [Offer收割]编程练习赛4

    描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元.并且如果消费总计满X元,还能享受优惠.小Ho是一个不薅羊毛不舒服斯基的人,他希望 ...

  6. hihocoder [Offer收割]编程练习赛61

    [Offer收割]编程练习赛61 A:最小排列 给定一个长度为m的序列b[1..m],再给定一个n,求一个字典序最小的1~n的排列A,使得b是A的子序列. 贪心即可,b是A的子序列,把不在b中的元素, ...

  7. ACM学习历程—Hihocoder [Offer收割]编程练习赛1

    比赛链接:http://hihocoder.com/contest/hihointerview3/problem/1 大概有一个月没怎么打算法了.这一场的前一场BC,也打的不是很好.本来Div1的A和 ...

  8. hihocoder offer收割编程练习赛8 C 数组分拆

    思路:(引自bfsoyc的回答:http://hihocoder.com/discuss/question/4160) 动态规划.状态dp[i]表示 前i个数的合法的方案数,转移是 dp[i] = s ...

  9. 【[Offer收割]编程练习赛14 D】剑刃风暴(半径为R的圆能够覆盖的平面上最多点数目模板)

    [题目链接]:http://hihocoder.com/problemset/problem/1508 [题意] [题解] 求一个半径为R的圆能够覆盖的平面上的n个点中最多的点数; O(N2log2N ...

随机推荐

  1. Nginx或Apache通过反向代理配置wss服务

    nginx配置参考 前提条件及准备工作: 1.假设ws服务监听的是8282端口(websocket协议) 2.已经申请了证书(pem/crt文件及key文件)放在了/etc/nginx/conf.d/ ...

  2. (转载)常用正则表达式大全!(例如:匹配中文、匹配html)

    正则匹配java注意点: 如果加 ^[\n]* 表示替换遇到 \n 的前后内容,如果加[\n]表示替换\n本处内容 原文地址:http://blog.csdn.net/dl020840504/arti ...

  3. web.config或App.config中AttachDBFilenamex相对路径问题

    <add name="employeeManagerConnectionString" connectionString="Data Source=.\SQLExp ...

  4. jQuery-表格属性

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 从PHP官方镜像创建开发镜像

    https://xlange.com/post/dockerfile-baseon-official-php-image.html

  6. 如何运行ruby代码

    第一种,ruby -e 在命令行中运行下面命令,-e的意思是,把后面的字符串当作脚本执行 ruby -e "print 'hello'" 使用irb交互控制台 在命令行输入irb ...

  7. windows假装更新升级

    http://fakeupdate.net/ 进入这个网站,选择一款系统界面,按F11进去全屏 比较有趣

  8. MD5解密

      国外http://md5.rednoize.com/http://www.milw0rm.com/md5/list.php国内http://www.neeao.com/md5/http://www ...

  9. spring 的核心类JdbcTemplate 方法

    2018-11-29  10:28:02

  10. django migrate无效的解决方法

    遇到一个很奇怪的问题 python manage.py makemigrations 的时候显示要创建两张表,但是执行 python manage.py migrate 的时候不能识别,也就是说失效了 ...