博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
7.30二分及三分(组队的)
阅读量:6493 次
发布时间:2019-06-24

本文共 5646 字,大约阅读时间需要 18 分钟。

Problem A  

题目大意就是说有一根细丝,在受热后会膨胀产生形变,变为一个圆弧,给出圆弧变化前后的长度,求这根细丝在水平上升高了多少

解题过程:由于题目呢给定了说形变不会是细丝变为超过一个半圆的形状,所以我们就可以对形变的高度二分假设升高了x,那么设圆的半径为R,就存在公式

                                R^2 - (R-x)^2 = (L/2)^2       其中L是细丝变化前的长度

解出来                       R = x/2 + (L*L)/(8*x);

然后可以求出圆心角      Sita = 2 * asin((L/2) / R);

在比较R*Sita与L1(形变后的长度)   其实这里我也没有证明它在0~(L/2)之间是严格递增或是严格递减的,反而证明出了在这个区间他是有增有减的,所以我很郁闷,暂且只能放在这里了,代码是直接二分给出的,我三分求最大值后,再在最小到最大值之间二分反而错了,实在是无解了,网大神指点

1 #include 
2 #include
3 4 const double eps1 = 1e-4; 5 double L,L1,n,C; 6 7 int main() 8 { 9 while(~scanf("%lf%lf%lf", &L, &n, &C) && (L!=-1))10 {11 if(!L || !n || !C) {printf("0.000\n"); continue;}12 L1 = L * (1 + n * C);13 double l = 0, r = L/2,mid,R,Sita;14 while(r-l>eps1)15 {16 mid = (l+r)/2;17 R = mid/2 + L*L/mid/8;18 Sita = 2 * asin(L/2/R);19 if(Sita * R > L1) r = mid;20 else l = mid;21 }22 printf("%.3lf\n", mid);23 }24 return 0;25 }

 

 

Problem B  

还没有搞出

 

 

Problem C  

题目大意是说给出n个牛棚和m头牛,目标是将m头牛放进n个牛棚中去,且要让他们两两之间的距离尽量大,求这时最小的两个有牛的牛棚之间的距离

目标是要让有牛的牛棚之间的距离尽量大,且那时距离最小的两个牛棚之间的距离,那我们就可以直接二分这个最小距离,如果当前这个最小距离可以满足把所有的牛全部放进去,而且还有多的牛棚,那就二分他与最大值之间的距离,否则二分他与最小值之间的中点

以下是章爷的代码

1         #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #define LL long long 9 using namespace std;10 const int inf=0x3f3f3f3f;11 const int maxn=100000+10;12 int x[maxn],c,n;13 int judge(int val)14 {15 int i,sum=1,cur=0;16 for(i=1;i
=val)20 {21 sum++;22 cur=0;23 }24 else cur+=x[i];25 }26 if(sum==c) return 1;27 else return 0;28 }29 int main()30 {31 cin>>n>>c;32 int i;33 for(i=0;i
=1;i--) x[i]=x[i]-x[i-1];36 int low=0,high=1000000001,mid;37 while(high>low)38 {39 mid=low+(high-low)/2;40 if(judge(mid)) low=mid+1;41 else high=mid;42 }43 printf("%d\n",low-1);44 return 0;45 }

 

Problem D  

题目是说给出一系列的A,B和C,以及一些和sum,要你对每一个sum从A,B和C数组中分别找出一个使他们的和为当前这个sum,最开始做的时候哦直接枚举A和B,然后用sum减去每一个C,再二分这个数组,居然发现超时了。

仔细一分析,有1000个sum,500个A,500个B,再加上二分sum-C,时间复杂度就是O(1000 * 500 * 500 * log500),明显超时了,后来章爷突发灵感,吧A+B保存起来,再对每一个sum-C数组,二分A+B这样复杂度就是O(1000 * 500 * log250000),可以过了,挂拉呱啦敲完了,过了!!!膜拜章爷啊啊啊~~~

1 #include 
2 #include
3 using namespace std; 4 5 int a[505],b[505],c[505],ab[250005]; 6 int A,B,C,AB,X,S; 7 8 int find_AB(int sum) 9 {10 int l=0,r=AB-1;11 while(l<=r)12 {13 int x=(l+r)>>1;14 if(sum == ab[x]) return 1;15 else if(sum < ab[x]) r = x-1;16 else l=x+1;17 }18 return 0;19 }20 21 22 int main()23 {24 int Case=1;25 while(~scanf("%d%d%d",&A, &B, &C))26 {27 for(int i=0;i

 

 

Problem E   简单的二分

1 #include 
2 #include
3 #define eps 1e-10 4 5 double f(double x) 6 { 7 return 8*pow(x,(double)4) + 7*pow(x,(double)3) + 2*pow(x,(double)2) + 3*x + 6; 8 } 9 10 int main()11 {12 int T;13 while(~scanf("%d", &T))while(T--)14 {15 double l = 0, r = 100, x, y;16 scanf("%lf", &y);17 if(y<6 || f(100)
y)r = x;24 else break;25 }26 printf("%.4lf\n", x);27 }28 return 0;29 }

 

 

Problem F

求函数的最小值,就只需要将方程求导,倒数为0的点就是所求,接下来就是同上了

1 #include 
2 #include
3 #define eps 1e-10 4 5 double x,y; 6 7 double f(double x) 8 { 9 return 42*pow(x,(double)6) + 48*pow(x,(double)5) + 21*pow(x,(double)2) + 10*x ;10 }11 12 double g(double x)13 {14 return 6 * pow(x,7)+ 8*pow(x,6) + 7*pow(x,3) + 5*pow(x,2) - y*x;15 }16 17 int main()18 {19 int T;20 while(~scanf("%d", &T))while(T--)21 {22 double l = 0, r = 100;23 scanf("%lf", &y);24 if(y<6 || f(100)
y)r = x;31 else break;32 }33 printf("%.4lf\n", g(x));34 }35 return 0;36 }

 

 

Problem G  

这道题要求从0 0 打到x y已知初速度的最小出射角度,我的方法是按照公式

y = Vsin(Sita)*t - G*t^2/2和

x = Vcos(Sita)*t;

对于已知可以达到x求出可以达到最高的y的角度,再在0到这个范围二分

之所以要求出到达x时所能到达的最高高度,是由于将t消去(下面的式子代入上式)后,y不是单调函数而是先增后减,而题目又是要求最小的出射角,那我们必然可以求出最大高度时的角度,那么角度在0到这个范围中一定有一个是原来的解,二分即可

1 #include 
2 #include
3 const double eps = 1e-10; 4 const double eps1 = 1e-7; 5 const double pi = 4 * atan(1.0); 6 const double G = 9.8; 7 double V, x, y; 8 9 10 double f(double sita)11 {12 return V*sin(sita)*x/(V*cos(sita)) - (G*x*x) / ( 2 * V * V * (cos(sita) * cos(sita)) ) ;13 }14 15 int main()16 {17 int T;18 while(~scanf("%d", &T))while(T--)19 {20 scanf("%lf %lf %lf", &x, &y, &V);21 22 if(x==0 && (V*V/(2*G)-y) > eps ){printf("%lf\n",pi/2); continue;}23 else if(x==0 && (y - V*V/(2*G))>eps ){printf("-1\n"); continue;}24 25 double l = 0, r = pi/2+0.5;26 double mid = 0, midmid = pi/2;27 while(midmid - mid > eps)28 {29 mid = (l+r)/2;30 midmid = (mid+r)/2;31 double mid_val = f(mid);32 double midmid_val = f(midmid);33 if(midmid_val < mid_val) r = midmid;34 else l = mid;35 }36 if(y > f(mid)){printf("-1\n"); continue;}37 double ans = 0;38 l = 0, r = mid;39 while(1)40 {41 mid = (l+r)/2;42 double temp = f(mid);43 if(fabs(y - temp) < eps1){ans = mid;break;}44 else if(temp < y) l = mid;45 else r = mid;46 }47 printf("%lf\n", ans);48 }49 return 0;50 }

 

Problem H  

暂未搞出

 

转载于:https://www.cnblogs.com/gj-Acit/p/3234096.html

你可能感兴趣的文章
Filter案例用户自动登录学习笔记
查看>>
阿里云内网和公共NTP服务器
查看>>
c++ 正则表达式邮箱
查看>>
C 提高1 内存四区 变量本质 栈开口方向 指针铁律1
查看>>
QT windows平台安装
查看>>
Outlook 2003 邮件不能显示图片
查看>>
1+1*2+1*2*3+1*2*3*n数列的求和算法
查看>>
异常模拟测试 -- 场景抽象及解决方案
查看>>
Gradle之旅-can not find tools.jar问题解决
查看>>
JavaScript_navigator
查看>>
apache配置文件详解
查看>>
linux下echo的使用总结
查看>>
EDM营销学堂:高效提升营销邮件点击率的技巧
查看>>
ORACLE 11G静默安装配置分解
查看>>
为什么大家不相信国产虚拟化技术?
查看>>
华为首提“业务驱动基础架构”(SDI)
查看>>
Word2010使用技巧之一:熟悉功能区
查看>>
Citrix XenDektop 7 实施十 创建License Server
查看>>
RookeyFrame 通用页面 加载数据 原理
查看>>
hbuilder APP服务器端(C#)推送
查看>>