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]相关数据

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll; int h[];
int a[];
int c[];
int main()
{
int i,n,j,k;
memset(h,,sizeof(h));
memset(c,,sizeof(c));
scanf("%d",&n);
for(i=;i<n;i++)
{
scanf("%d",a+i);
c[a[i]]++;
}
for(i=;i<n;i++)
{
for(j=;j<n;j++)
{
h[a[i]+a[j]]++;
}
}
ll ans=;
for(i=;i<n-;i++)
{
for(j=i+;j<n;j++)
{
if((a[i]+a[j])%==)
h[a[i]+a[j]]-=c[(a[i]+a[j])/];
h[a[i]+a[j]]-=c[a[j]]*;
h[a[i]+a[j]]-=c[a[i]]*;
h[a[i]+a[j]]+=;
h[a[i]+a[i]]+=;
h[a[j]+a[j]]+=;
ans+=h[a[i]+a[j]];
if((a[i]+a[j])%==)
h[a[i]+a[j]]+=c[(a[i]+a[j])/];
h[a[i]+a[j]]+=c[a[j]]*;
h[a[i]+a[j]]+=c[a[i]]*;
h[a[i]+a[j]]-=;
h[a[i]+a[i]]-=;
h[a[j]+a[j]]-=;
}
}
printf("%lld\n",ans/);
return ;
}

B.投掷硬币

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

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

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll; double p[];
double dp[][];
int main()
{
int i,j,m,n;
scanf("%d%d",&n,&m);
for(i=;i<n;i++)
scanf("%lf",p+i);
memset(dp,,sizeof(dp));
int old=,now=;
dp[][]=;
for(i=;i<n;i++)
{
old^=,now^=;
memset(dp[now],,sizeof(dp[now]));
for(j=;j<i+;j++)
{
dp[now][j]+=dp[old][j]*(-p[i]);
dp[now][j+]+=dp[old][j]*p[i];
}
}
printf("%lf\n",dp[now][m]);
return ;
}

C.可疑的记录

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

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

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

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std; const int N =; int head[][N],cnt[]={,};
int to[][N<<],next1[][N<<];
bool isCircle[N<<];
bool vis[N];
bool ans[N]; void addedge(int u,int v,int i)
{
to[i][cnt[i]]=v;
next1[i][cnt[i]]=head[i][u];
head[i][u]=cnt[i]++;
} int dfs(int u,int eno)
{
vis[u]=true;
int cn=-;
for(int i=head[][u];i!=-;i=next1[][i])
{
if(i == (eno^))
continue;
int v=to[][i];
if(vis[v])
{
cn=v;
isCircle[i/]=true;
vis[u]=false;
return cn;
}
cn = dfs(v,i);
if(cn!=-)
{
isCircle[i/]=true;
vis[u]=false;
if(cn == u)
return -; return cn;
}
}
vis[u]=false;
return cn;
} int inc[N],ouc[N];
int e[N][];
int main()
{
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
memset(isCircle,,sizeof(isCircle));
memset(inc,,sizeof(inc));
memset(ouc,,sizeof(ouc));
memset(ans,,sizeof(ans));
int i,n,u,v;
scanf("%d",&n);
int in0=n;
for(i=;i<n;i++)
{
scanf("%d%d",&u,&v);
u--,v--;
e[i][]=u;
e[i][]=v;
addedge(u,v,);
addedge(u,v,);
addedge(v,u,);
if(inc[v]==)in0--;
ouc[u]++;inc[v]++;
}
dfs(,-);
bool first=true;
for(i=;i<n;i++)
{
if(!isCircle[i])continue;
u=e[i][];
v=e[i][];
ouc[u]--;inc[v]--;
if(inc[v]==)in0++;
if(in0 == && inc[] == )
{
ans[i]=true;
if(!first)putchar(' ');
printf("%d",i+);
first=false;
}
if(inc[v]==)in0--;
ouc[u]++;inc[v]++;
}
putchar('\n');
return ;
}

D.剑刃风暴

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

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

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

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

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

就像这样:

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

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

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

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

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm> #define Mn 2005//平面点集中点数 using namespace std; const double eps = 1e-;//精度调高点没跑~
const double pi = acos(-1.0); #define sqr(x) ((x) * (x)) double R;//定长 struct point
{
double x,y;
void read()
{
scanf("%lf%lf",&x,&y);
} void print()
{
printf("%lf%lf\n",x,y);
} double friend dis(const point &a,const point &b)
{
return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
} } p[Mn + ]; struct alpha
{ double v;
bool flag;
bool friend operator <(const alpha &a,const alpha &b)//排序专用偏序关系
{
return a.v < b.v;
} } alp[Mn * Mn + ]; //C(N,2)*2的可能交点(可能极角) void solve(int n,int r)
{
R = r;//本题内为单位圆
for(int i = ; i < n; i++)
p[i].read(); int MAX = ;
for(int i = ; i < n; i++)
{
int t = ;
for(int j = ; j < n; j++)
{
if(i == j)
continue; double theta,phi,D;
D = dis(p[i],p[j]);
if(D > 2.0 * R)//距离超界直接秒杀
continue; //关键部分
theta = atan2(p[j].y - p[i].y,p[j].x - p[i].x);
if(theta < )
theta += * pi;
phi = acos(D / (2.0 * R));
alp[t].v = theta - phi + * pi;
alp[t].flag = true;
alp[t + ].v = theta + phi + * pi;
alp[t + ].flag = false;
t += ;
} sort(alp,alp + t);
int sum = ;
for(int j = ; j < t; j++)
{
if(alp[j].flag)
sum ++;
else
sum --;
if(sum > MAX)
MAX = sum;
}
}
printf("%d\n",MAX + );
} int main()
{
int n,r;
while(~scanf("%d%d",&n,&r))
{
solve(n,r);
}
}

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. js不能拦截302

    302跳转是浏览器自动处理并跳转 You can't handle redirects with XHR callbacks because the browser takes care of the ...

  2. Cocos Creator 键盘监听事件

    键盘事件键盘.设备重力传感器此类全局事件是通过函数 cc.systemEvent.on(type, callback, target) 注册的.cc.SystemEvent.EventType.KEY ...

  3. 初识github之注册和基本概念

    通过大量的网络资源,我粗浅了解了GitHub是什么:一个开源的代码存储云平台,它的logo是一只 “章鱼猫(Octocat)”.那么开始学习GitHub第一部分——注册GitHub账号. 首先英文就让 ...

  4. maven的下载,安装配置以及build一个java web项目

    一.下载 下载地址:http://maven.apache.org/download.cgi 二.安装 下载完成后,解压,进入到bin目录: 三.环境变量配置 复制bin目录下的文件的路径(如:xxx ...

  5. 学习笔记: ES7(ES2016)新功能

    ES7添加了两个新功能 : 1. Array.prototype.includes() 2. 指数运算符 1 .Array.prototype,includes() 判断指定的元素是否存在于数组中,  ...

  6. Lua class

    local _class = {} function class(super) local class_type = {} class_type.ctor = false class_type.sup ...

  7. EL语言表达式 (三)【EL中的算术运算以及判断EL对象是否为空】

    一.EL中的算术运算 EL和其他语言一样,同样也提供了基本的算术运算(加.减.乘.除和取余),如下图. 运算符 功能 示例 结果 + 加 ${19+1} 20 - 减 ${66-30} 36 * 乘 ...

  8. programmatically detect whenever test run is in debug mode

    if (System.Diagnostics.Debugger.IsAttached)    // code or timeout value when running tests in debug ...

  9. TP父类及模板继承

    一.TP父类方法继承 session用法 用登录页面做例子 <?php namespace Home\Controller; use Think\Controller; class LoginC ...

  10. 关于python中selector问题

    在做大型的爬虫时,re表达式往往效率不高,scrapy框架为爬虫提供了很好的爬虫方法 scrapy提取数据时有一套自己的机制,即selectors,一般通过特定的XPath,或者特定 的CSS表达式来 ...