网址:CSUST 7月30日(二分和三分)

这次的比赛是二分&三分专题,说实话以前都没有接触过二分,就在比赛前听渊神略讲了下.......不过做着做着就对二分熟悉了,果然做题是学习的好方法啊~~~~\(≧▽≦)/~啦啦啦,不过我们这组每次都是刚开始垫底,然后才慢慢追上去.......真担心爆零,但是结果还不错,和第一做的题目一样多,差的只是错误率和时间。

A:大意是:给你一个直线和一个弧线,(弧线是圆的一部分),求弧线高出直线的高度。POJ 1905   Expanding Rods

解法:先确定半径的范围再进行二分,r1=l/2,半径不可能再小了,再假设r2=l,求出所对应的弧长,若小于所给的长度,则取l,若大于,则r2=r2*2。再二分取对应的半径,最后带入,求高度差。注意!!!!!在这里半径越大,弧长反而越小!!!!!!还有c,n==0的时候要提出来讲,==0时,弧长=l,直接高度==0;

代码:    16MS

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
double l;
double f(double r) //求弧长
{
return (asin(l/r/)**r); //asin()是反三角函数
}
double g(double r) //求高度差
{
return r-cos(asin(l/(r*)))*r;
}
int main()
{
double c;
double n,r1,r2,mid,sum,w;
while(~scanf("%lf%lf%lf",&l,&c,&n))
{
sum=l*(+n*c);
if(l<&&c<&&n<)
break;
if(c==||n==) //为零的时候要另外讲.......
{
printf("0.000\n");
continue;
}
r1=l/; //半径不可能比l/2更小
r2=l;
while(f(r2)>=sum)//注意,半径越大,所对应的弧长越小......在这错了好久都没检查出来....
r2=*r2;
while(f(r1)-f(r2)>1e-)
{
mid=(r1+r2)/;
w=f(mid);
if(w>sum)
r1=mid;
else if(w<sum)
r2=mid;
else if(w==sum)
break;
}
printf("%.3lf\n",g(mid));
}
return ;
}

B 大意是:给你n个点,找出任意4个点组合,有几个正方形   Squares

思路:先任意找两个点,确定一条边,确定一个正方形,再寻找另外两个点,若能找到则有正方形,计数+1。

代码:     1500MS

 #include <stdio.h>
#include <string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int n; /* 点的个数 */
struct Point
{
int x;
int y;
}point[];
bool comp1(Point i,Point j)
{
if(i.x<j.x)
return true;
else if(i.x==j.x)
{
if(i.y<j.y)
return true;
}
return false;
}
//由于点已经按照坐标排序过,所以采用二分查找
//搜索点(x,y)是否存在,存在返回1,否则返回0
int bsearch(int x, int y)
{
int m, s, t;
s = ;
t = n-;
while (s <= t)
{
m = (s+t)/;
if (point[m].x == x && point[m].y == y) return ;
if (point[m].x > x || (point[m].x == x && point[m].y > y))
t = m-;
else
s = m+;
}
return ;
} int main()
{
int x, y, i, j, count;
while (scanf("%d", &n), n)
{
count = ;
for (i = ; i < n; i++)
scanf("%d %d", &point[i].x, &point[i].y);
//插入法对点排序,按照x从小到大,y从小到大,且x优先排列的方式
// 枚举所有边,对每条边的两个顶点可以确定一个唯一的正方形,并求出另外两个顶点的坐标
sort(point,point+n,comp1);
for (i = ; i < n; i++)
for (j = (i+); j < n; j++)
{
//计算第三个点的坐标,搜索其是否存在
x = point[i].y-point[j].y+point[i].x;
y = point[j].x-point[i].x+point[i].y;
if (bsearch(x,y) == )
continue;
//计算第四个点的坐标,搜索其是否存在
x = point[i].y-point[j].y+point[j].x;
y = point[j].x-point[i].x+point[j].y;
if (bsearch(x, y))
count++;
}
printf("%d\n", count/);
}
return ;
}

C 大意是:有m个仓库,n头牛,要把牛放到仓库里,要使两两之间的距离尽可能的大,输出最小的距离。Aggressive cows

不断假设满足的距离;

代码:       110MS

 #include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int N,C,a[];
int juge(int m)
{
int number=,i,frontt=;
for(i=;i<N;i++)
{
if((a[i]-a[frontt])>=m) //判断m是不是最小的距离
{
frontt=i;
number++;
if(number==C) return ;//所有的牛都放进去了,满足
}
}
return ;
} int main()
{
int i,midd,left,right;
scanf("%d%d",&N,&C);
for(i=;i<N;i++)
scanf("%d",&a[i]);
sort(a,a+N);
left=;
right=a[N-]-a[];
while(left<=right) //当l和r交叉错过时就跳出
{
midd=(left+right)/;
if(juge(midd))
left=midd+;//m可能小了
else
right=midd-; //m太大
}
printf("%d\n",left-);
return ;
}

D大意是:给出3个数组,从每个数组中挑一个出来加起来成一个数,问是否能组成所给的数。  Can you find it?

代码:    359MS,时限是3000MS

方法是合并a,b两个数组,变成了只有两个数组去凑数了。

 #include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
int ab[],k;
int f(int x)
{
int l=,r=k,mid;
while(l<=r) //同C的判断方法一样 ,l,r错开就跳出
{
mid=(r+l)/;
if(ab[mid]==x)
return ;
if(ab[mid]<x)
l=mid+;
else
r=mid-;
}
return ;
}
int main()
{
int l,m,n,i,j,o=,s,w,a[],b[],c[];
while(~scanf("%d%d%d",&l,&m,&n))
{
k=;
for(i=;i<l;scanf("%d",&a[i++]));
for(i=;i<m;scanf("%d",&b[i++]));
for(i=;i<n;scanf("%d",&c[i++]));
for(i=;i<l;i++)
for(j=;j<m;j++)
ab[k++]=a[i]+b[j]; //合并a,b两组数
sort(c,c+n);
sort(ab,ab+k);
for(printf("Case %d:\n",o++),scanf("%d",&s);s;s--)
{
scanf("%d",&w);
j=;
for(i=;i<n;i++)
if(f(w-c[i]))
{
j++;
break;
}
if(j)
printf("YES\n");
else
printf("NO\n");
}
}
return ;
}

E 大意是:给出一个方程:8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,给出Y,要求求出X,给定X属于[0~100],如果不是在这个范围则输出No solution。

代码:   0MS     Can you solve this equation?

 #include<stdio.h>
#include<math.h>
int main()
{
int y,T;
scanf("%d",&T);
while(T--)
{
double l=,r=,mid,sum;
scanf("%d",&y);
if(y<||y>) //X小于0和大于100的情况,无解
{
printf("No solution!\n");
continue;
}
while(r-l>1e-)
{
mid=(r+l)/; //二分
sum=pow(mid,)*+*pow(mid,)+mid*mid*+*mid+;
if(sum>y)
r=mid;
else if(sum<y)
l=mid;
else if(sum==y)
break;
}
printf("%.4lf\n",mid);
}
return ;
}

F 大意是:F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100),这个方程,给出Y,求X使得F(X)的值最小,给出X的范围0~100。

思路,因为这不是个单调函数,所以要用三分做。     0MS     Strange fuction

 #include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
double y;
double dis(double x)
{
return *pow(x,)+*pow(x,)+*pow(x,)+*x*x-y*x; //方程
}
int main()
{
double left,right,mid,mmid,t2,t1;
int t;
scanf("%d",&t);
while(t--)
{
mid=;mmid=;
scanf("%lf",&y);
left=;right=;
while(fabs(mid-mmid)>1e-)
{
mid=left/+right/; //三分
mmid=mid/+right/;
t2=dis(mid);t1=dis(mmid);
if(t2>t1)
{
left=mid;
}
else if(t2<t1)
{
right=mmid;
}
else
break;
}
printf("%.4lf\n",t1);
}
return ;
}

G 大意是:给出人在(0,0)这一点,目标在x,y,给出出箭的速度V,求能射到目标的最小角度   Toxophily

有两种方法,一是用纯数学方法,二是用三分+二分。不过都先要找到x,y的关系式:x^2*g/(2*v^2)*tan^2(ß) - x*tan(ß) +y + x^2*g/(2*v^2) = 0;

先是第一种方法,把tanB看做未知数,就变成一个AX^2+BX+C=0的一元二次方程,当△<0时无解,输出-1,△=0时只有一个值,△>0时有两解,取>0,<90的解;取小得那个解。

代码:     0MS

 #include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
const double g=9.8;
int main()
{
int t;
double x,y,v,k,s,d;
cin>>t;
while(t--)
{
scanf("%lf%lf%lf",&x,&y,&v);
k=x*x-*g*x*x/v/v*(y+0.5*g*x*x/v/v); //△
if(k<)
{
printf("-1\n");
}
else
{
s =(x-sqrt(k))*v*v/g/x/x; //小的根
if(s<)
s=(x+sqrt(k))*v*v/g/x/x; //大的根
d=atan(s); //反三角函数
printf("%.6lf\n",d);
}
}
return ;
}

第二种方法:先用三分在0~90°之间找到最大值,如果最大值<y,则无解,输出-1,否则在0~t,之间二分,找到合适的角度。

代码来自:   http://blog.csdn.net/hello_there/article/details/8519008      0MS

 #include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const double eps=1.0e-9;
const double PI=acos(-1.0);
const double g=9.8;
double x,y,v; double f(double t)
{
return x*tan(t)-g*x*x//(v*v*cos(t)*cos(t));
}
double two_devide(double low,double up)
{
double m;
while(up-low>=eps)
{
m=(up+low)/;
if(f(m)<=y)
low=m;
else
up=m;
}
return m;
}
double three_devide(double low,double up)
{
double m1,m2;
while(up-low>=eps)
{
m1=low+(up-low)/;
m2=up-(up-low)/;
if(f(m1)<=f(m2))
low=m1;
else
up=m2;
}
return (m1+m2)/;
}
int main()
{
int t;
double maxt;
cin>>t;
while(t--)
{
cin>>x>>y>>v;
maxt=three_devide(,PI/);
if(f(maxt)<y)
printf("-1\n");
else
printf("%.6lf\n",two_devide(,maxt));
}
return ;
}

H大意是:有n个精灵,要去同一个地方开会,他的不高兴程度=S^3*W,S,要走的距离,W,他的体重。求最小的不高兴的和。因为不确定函数的单调性,所以用三分。

代码:     Party All the Time

 #include<iostream>
#include<algorithm>
#include<stdio.h>
#include<math.h>
using namespace std;
struct line
{
double bumanyi; //体重
double area; //所在的位置
}a[];
bool comp1(line x,line y)
{
return x.area<y.area;
}
int main()
{
double mid,mmid,left,right,t1,t2;
int t,i,n,w=;
scanf("%d",&t);
while(t--)
{
w++;
mid=;mmid=;
scanf("%d",&n);
for(i=;i<n;i++)
scanf("%lf %lf",&a[i].area,&a[i].bumanyi);
sort(a,a+n,comp1); //排序
left=a[].area;
right=a[n-].area; //范围
while(fabs(mid-mmid)>1e-)
{
t1=;t2=;
mid=left/+right/; //三分
mmid=mid/+right/;
for(i=;i<n;i++)
{
t1+=fabs((a[i].area-mid)*(a[i].area-mid)*(a[i].area-mid))*a[i].bumanyi;
t2+=fabs((a[i].area-mmid)*(a[i].area-mmid)*(a[i].area-mmid))*a[i].bumanyi;
}
if(t1>t2)
left=mid;
else if(t1<t2)
right=mmid;
else
break; }
printf("Case #%d: %.lf\n",w,t1);
}
return ;
}

不过这题的时限是2000MS,这个代码却用了1656,再在网上找个优化的代码。

网上的代码:531MS    其实只是把求和那用了个函数,时间就只有1/3........

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
double ab(double x)
{
return x>?x:-x;
}
struct node
{
double x;
double w;
}q[];
int n;
double cal(double xi)
{
int i;
double res=;
for(i=;i<n;i++)
{
double t=ab(q[i].x-xi);
res+=t*t*t*q[i].w;
}
return res;
}
int main()
{
int ca=,i,t;
double l,r,m,mm,ans;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=;i<n;i++)
scanf("%lf%lf",&q[i].x,&q[i].w);
l=q[].x;
r=q[n-].x;
while(l<r)
{
if(ab(r-l)<=0.001)
break;
m=(l+r)/;
mm=(m+r)/;
if(cal(m)<cal(mm))
{
ans=cal(m);
r=mm;
}
else l=m;
}
printf("Case #%d: ",ca++);
printf("%.0lf\n",ans);
}
return ;
}

第二次组队赛 二分&三分全场的更多相关文章

  1. HDU 2298 Toxophily 【二分+三分】

    一个人站在(0,0)处射箭,箭的速度为v,问是否能够射到(x,y)处,并求最小角度. 首先需要判断在满足X=x的情况下最大高度hmax是否能够达到y,根据物理公式可得 h=vy*t-0.5*g*t*t ...

  2. CF 8D Two Friends 【二分+三分】

    三个地点构成一个三角形. 判断一下两个人能否一起到shop然后回家,如果不能: 两个人一定在三角形内部某一点分开,假设沿着直线走,可以将问题简化. 三分从电影院出来时候的角度,在对应的直线上二分出一个 ...

  3. Codeforces Gym100543B 计算几何 凸包 线段树 二分/三分 卡常

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF-Gym100543B.html 题目传送门 - CF-Gym100543B 题意 给定一个折线图,对于每一条 ...

  4. Toxophily-数论以及二分三分

    G - Toxophily Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submi ...

  5. CodeForces - 1059D——二分/三分

    题目 题目链接 简单的说,就是作一个圆包含所有的点且与x轴相切,求圆的最小半径 方法一 分析:求最小,对半径而言肯定满足单调性,很容易想到二分.我们二分半径,然后由于固定了与X轴相切,我们对于每一个点 ...

  6. uva 1463 - Largest Empty Circle on a Segment(二分+三分+几何)

    题目链接:uva 1463 - Largest Empty Circle on a Segment 二分半径,对于每一个半径,用三分求出线段到线段的最短距离,依据最短距离能够确定当前R下每条线段在[0 ...

  7. [CSP-S模拟测试]:柱状图(树状数组+二分+三分)

    题目描述 $WTH$获得了一个柱状图,这个柱状图一共有$N$个柱子,最开始第$i$根柱子的高度为$x_i$,他现在要将这个柱状图排成一个屋顶的形状,屋顶的定义如下:$1.$屋顶存在一个最高的柱子,假设 ...

  8. HDU2899Strange fuction(二分/三分)

    传送门 题目大意:求 F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100):的最小值 题解:求个导,二分导函数零点,就是原函数最小值所在的 ...

  9. 2020牛客寒假算法基础集训营5 B.牛牛战队的比赛地 (二分/三分)

    https://ac.nowcoder.com/acm/contest/3006/B 三分做法 #include<bits/stdc++.h> #define inf 0x3f3f3f3f ...

随机推荐

  1. iOS 图像处理 - 图像拼接

    解决这个问题:将两个图像拼接在一起 前提:须要加入Framework:CoreGraphics.framework 源代码: - (UIImage *) combine:(UIImage*)leftI ...

  2. WCF学习笔记——不支持内容类型 text/xml; charset=utf-8

    我在使用WCF的时候,客户端运行报错: 不支持内容类型 text/xml; charset=utf-8 原因是WCF服务做了修改.刷新客户端的服务引用,问题消失 =================== ...

  3. NYOJ15括号匹配

    NYOJ15括号匹配 括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6   描述 给你一个字符串,里面只包含"(",")" ...

  4. DCloud-MUI:AJAX

    ylbtech-DCloud-MUI:AJAX 1.返回顶部 1.   2. 2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部 1. http://dev.dcloud.net.cn ...

  5. [SpringMVC]定义多个前缀映射的问题

    转自:https://penciltim.iteye.com/blog/501073 我在web.xml里面定义多个dispatch-servlet的前缀映射,像下面这样 <!-- Servle ...

  6. 第2章 安装Nodejs 2-4 Linux下安装Nodejs

    linux下编译安装Nodejs  GCC和G++分别是GNU的C和C++编译器.它们在执行编译工作的时候把源代码通过预处理转化成汇编语言生成.i后缀的文件,再由汇编变成目标机器代码,最后连接目标代码 ...

  7. 线性预测与Levinson-Durbin算法实现

    在学习信号处理的时候,线性预测是一个比较难理解的知识点,为了加快很多朋友的理解,这里给出Levinson-Durbin算法的线性预测实现和一个测试Demo,Demo中很明确的把输入信号.预测信号.预测 ...

  8. JVM命令参数指南

    1.调整最大堆内存 -Xmx 8192m 2.调整最小堆内存-Xmx 8192m3.设置虚拟机垃圾回收机制-XX:+UseG1GC4.收集垃圾日志信息-Xloggc:/D:gc.log5.OOM异常之 ...

  9. 使用 SqlBulkCopy 批量插入数据

    /// <summary> /// 使用SqlBulkCopy将DataTable中的数据批量插入数据库中 /// </summary> /// <param name= ...

  10. Asp.net MVC4 Step By Step(5)-使用Web API

    Web API是ASP.net MVC4新增的一个特色, 应用于处理Ajax请求, 他同时使用了Web标准规范, 比如Http, Json,和XML,以及一系列构建REST数据服务的参考原则, 和AS ...