题目链接:HDU 2199
VJ链接:寒假第一练--二分搜索专题
第一次给大一的写题解,好激动有木有!
B题,首先来看题目描述,
Now,given the equation 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,can you find its solution between 0 and 100;
Now please try your lucky.
给你这么一个等式,让你找到有个0 ~ 100 之间的解。乍一看我的天,最高阶是4的方程这可怎么解?
别着急我们接着看输入INPUT
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has a real number Y (fabs(Y) <= 1e10);
题目给了我们Y。
那么问题就变成了求一元四次方程的解了,我刚查了一下还真有4次方乘的求根公式的!这里不再赘述感兴趣的移步百度百科
其实我们可以通过计算机的超高运算速度去解决这个问题。直接枚举?这里的解是实数显然不行,而acm中与实数相关的问题都涉及到精度,
我们可以通过基础的二分搜索来不断缩小解的范围来提高答案的精度直到满足条件。
【常见的二分】
常见的二分一般是查找数组中的元素的位置或者存不存在。
基础比较弱的同学可以自己多写几遍,最好去实现一下文章底部给出的lower_bound,upper_bound。
int binSearch(int List[] ,int x,int head,int tail){ //循环版本
while(head<=tail){
int mid=(head+tail)/2;
if(List[mid]==x)
return mid;
else if(List[mid]>x){ //注意别写反
tail=mid-1;
}
else{
head=mid+1;
}
}
return -1;
}
这里是实数,稍稍改变一下。
#include<iostream>
#include<cstdio>
using namespace std;
const double eps = 1e-10; //c++中推荐写法,等价于c的 #define eps 1e-10
double ans(double x){
return 8*x*x*x*x + 7*x*x*x + 2*x*x + 3*x + 6;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
double Y;
scanf("%lf",&Y);
if(Y > ans(100) || Y<ans(0)) //找不到的情况
printf("No solution!\n");
else{
double l = 0,r = 100; //解在 0 ~ 100
while(r - l >eps){ //注意这里,如果我们的解的范围大于 eps,那么我们继续二分 (这里我用1e-5结果与样例差0.001,索性直接用了1e-10)
double mid = (l + r)/2;
if(ans(mid) < Y)
l = mid;
else
r = mid ;
}
printf("%.4f\n",l);
}
}
return 0;
}
二分搜索,就这么简单,剩下的题目,除了C题应该都能抽象出二分搜索的模型来,加油去AC吧!
安利一发STL中的二分 lower_bound upper_bound的简单实现(STL) 。