网址: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. Hypercall

    在Linux中.大家应该对syscall很的了解和熟悉,其是用户态进入内核态的一种途径或者说是一种方式.完毕了两个模式之间的切换:而在虚拟环境中,有没有一种类似于syscall这样的方式.可以从no ...

  2. Android View的onTouch和onClick和onLongClick事件

    这三个事件的调用顺序是: onTouch->onLongClick->onClick 先看这三个事件的处理函数: public boolean onTouch(View v, Motion ...

  3. 杂项-人物:Alan cooper

    ylbtech-杂项-人物:Alan cooper Alan Cooper ,“VB之父”“交互设计之父”,荣获视窗先锋奖(Microsoft Windows Pioneer)和软件梦幻奖(Softw ...

  4. Find them, Catch them(并查集)

    http://poj.org/problem?id=1703 题意:有两个黑帮团伙,共n名团伙成员(不知道属于这两个黑帮中的哪一个).现在警察有一些信息,每条信息包含2个人的编号,如果给出A a b, ...

  5. C# 标准命名规范

    笔者从事开发多年,有这样一种感觉,查看一些开源项目,如Spring.Apache Common等源码是一件赏心悦目的事情,究其原因,无外两点:1)代码质量非常高:2)命名特别规范(这可能跟老外的英语水 ...

  6. Python描述符:property()函数的小秘密

    描述符:将某种特殊类型的类的实例指派给另一个类的属性(注意:这里是类属性,而不是对象属性).而这种特殊类型的类就是实现了__get__,__set__,__delete__这三个方法中的一个或多个的新 ...

  7. Spring Boot (8) 全局异常处理

    服务层和dao层的最终异常会交给controller处理,控制层的异常则会记录日志系统. 新建一个类用来处理异常,名字随便GlobalDefaultExceptionHandler.java,加上@C ...

  8. IBMWebsphere 使用jar包删除文件

    1. 先使用ant打包一个jar包,删除其他不要的目录和文件,仅保留一个空的xxx.war文件夹("xxx"对应was上的工程安装根目录) 2. 在文件夹下新建一个META-INF ...

  9. SQLServer 使用变量动态行转列

    drop table #testcreate table #test(    id int identity(1,1) primary key,    bizDate varchar(50),    ...

  10. mysql主从不同步,提示更新找不到记录

    查看丛库状态show slave status\G 从库原文提示:Last_Error: Coordinator stopped because there were error(s) in the ...