第二次组队赛 二分&三分全场
这次的比赛是二分&三分专题,说实话以前都没有接触过二分,就在比赛前听渊神略讲了下.......不过做着做着就对二分熟悉了,果然做题是学习的好方法啊~~~~\(≧▽≦)/~啦啦啦,不过我们这组每次都是刚开始垫底,然后才慢慢追上去.......真担心爆零,但是结果还不错,和第一做的题目一样多,差的只是错误率和时间。
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,他的体重。求最小的不高兴的和。因为不确定函数的单调性,所以用三分。
- #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 ;
- }
第二次组队赛 二分&三分全场的更多相关文章
- HDU 2298 Toxophily 【二分+三分】
一个人站在(0,0)处射箭,箭的速度为v,问是否能够射到(x,y)处,并求最小角度. 首先需要判断在满足X=x的情况下最大高度hmax是否能够达到y,根据物理公式可得 h=vy*t-0.5*g*t*t ...
- CF 8D Two Friends 【二分+三分】
三个地点构成一个三角形. 判断一下两个人能否一起到shop然后回家,如果不能: 两个人一定在三角形内部某一点分开,假设沿着直线走,可以将问题简化. 三分从电影院出来时候的角度,在对应的直线上二分出一个 ...
- Codeforces Gym100543B 计算几何 凸包 线段树 二分/三分 卡常
原文链接https://www.cnblogs.com/zhouzhendong/p/CF-Gym100543B.html 题目传送门 - CF-Gym100543B 题意 给定一个折线图,对于每一条 ...
- Toxophily-数论以及二分三分
G - Toxophily Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submi ...
- CodeForces - 1059D——二分/三分
题目 题目链接 简单的说,就是作一个圆包含所有的点且与x轴相切,求圆的最小半径 方法一 分析:求最小,对半径而言肯定满足单调性,很容易想到二分.我们二分半径,然后由于固定了与X轴相切,我们对于每一个点 ...
- uva 1463 - Largest Empty Circle on a Segment(二分+三分+几何)
题目链接:uva 1463 - Largest Empty Circle on a Segment 二分半径,对于每一个半径,用三分求出线段到线段的最短距离,依据最短距离能够确定当前R下每条线段在[0 ...
- [CSP-S模拟测试]:柱状图(树状数组+二分+三分)
题目描述 $WTH$获得了一个柱状图,这个柱状图一共有$N$个柱子,最开始第$i$根柱子的高度为$x_i$,他现在要将这个柱状图排成一个屋顶的形状,屋顶的定义如下:$1.$屋顶存在一个最高的柱子,假设 ...
- HDU2899Strange fuction(二分/三分)
传送门 题目大意:求 F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100):的最小值 题解:求个导,二分导函数零点,就是原函数最小值所在的 ...
- 2020牛客寒假算法基础集训营5 B.牛牛战队的比赛地 (二分/三分)
https://ac.nowcoder.com/acm/contest/3006/B 三分做法 #include<bits/stdc++.h> #define inf 0x3f3f3f3f ...
随机推荐
- BNU 13259.Story of Tomisu Ghost 分解质因子
Story of Tomisu Ghost It is now 2150 AD and problem-setters are having a horrified time as the ghost ...
- Python入门 不必自己造轮子
操作list list切片 字符串的分割 字符串的索引和切片 读文件 f = file('data.txt') data = f.read() print data f.close() 写文件 dat ...
- vs2010永久删除项目的相关操作
1.选中要删除的项目,在解决方案资源管理器中,直接左键点击一下即可.. 2.点击键盘的删除键“DElect”. 3.然后找到工程的目录后,删除项目.即可永久性删除不在需要的程序或者是项目.
- selenium3 + python - select定位
一.Select模块(index) 1.导入Select模块.直接根据属性或索引定位 2.先要导入select方法:from selenium.webdriver.support.se ...
- MYSQL日期时间字符串互转
--MYSQL date_format(date,'%Y-%m-%d') -------------->oracle中的to_char(); 日期时间转字符串 --MYSQL str_to_da ...
- React Component(dva)
Stateless Functional Components(3种方式) class App extends React.Component function App() const App= Re ...
- C语言笔记(一)
笑话一枚:程序员 A:“哥们儿,最近手头紧,借点钱?”程序员 B:“成啊,要多少?”程序员 A:“一千行不?”程序员 B:“咱俩谁跟谁!给你凑个整,1024,拿去吧.” =============== ...
- 微信小程序跳转以及跳转的坑
一.首先小程序的跳转方法有一下几种 js控制跳转 // 保留当前页面,跳转到应用内的某个页面 wx.navigateTo({ url: '../blueberry/blueberry' }); // ...
- Java导出Excel(附完整源码)
导出excel是咱Java开发的必备技能啦,之前项目有这个功能,现在将其独立出来,分享一下.所用技术就是SpringBoot,然后是MVC架构模式.废话不多说,直接上代码了,源码点末尾链接就可以下载. ...
- 深度学习应用在推荐系统的论文-----A Novel Deep Learning-Based Collaborative Filtering Model for Recommendation System
1.题目:一种新的基于深度学习的协同过滤推荐系统 2.摘要: 以协同过滤(CF)为基础的模型主要获取用户和项目的交互或者相关性.然而,现有的基于CF的方法只能掌握单一类型的关系,如RBM,它只能获取用 ...