Num 23 : HDOJ : 2199 Can you solve this equation? + HDOJ : 1969 Pie [ 二分法 ]

在处理计算数学上某函数零点的时候,我们通常是这样做的:

1. 先判断这个零点在某个单调区间 [ a,b ]上( 假设为递增区间 );

2. 之后判断 f(x) 在 (a+b)/2 [ a,b中点处 ]是否为零;

3. 若中点处大于零,b=( a+b )/2 ;否则,同理,a=( a+b )/2 ;

4. 重复2.3.过程,直到找到零点,或满足精度;

如图( 图片来自百度 ):

C语言基于这个原理,也有了自己的二分法;

二分法:

    在某一特定的序列之中[
通常是已经排过序的数列 ]寻找某一特殊值[ 满足条件的最大最小值 ]的方法;

与通常的寻找方式不同,二分法采用的是折半查找的方式,比一般的需要游历所有数据的方法更省事;

但是需要注意的是: 二分法只能处理排过序的数据,未排序的不能够直接使用二分法!!

   实现代码:

int Q(int left, int right, int path){
    int mid;
    while(left <= right){
        mid = (left + right) / 2;
        if( mid < path ) left = mid + 1;
        else  right = mid - 1;
   }return right;
}

需要定义至少四个变量: left , right , mid; path;

left: 区间的左边界;

right: 区间的右边界;

mid: 区间的中点;

path: 可否取得的极值;

   代码分析:

          当 left<right 时,执行程序;

通过mid的变化,不断接近 path,直到 right<left ;

left=mid+1; right=mid - 1 ;是为了保证程序在left=right=mid的时候,不会造成死循环;

例:HDOJ2199:

Can you solve this equation?

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 13146    Accepted Submission(s): 5886

Problem Description

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.

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);

Output

For each test case, you should just output one real number(accurate up to 4 decimal places),which is the solution of the equation,or “No solution!”,if there is no solution for the equation between 0 and 100.

Sample Input

2
100
-4

Sample Output

1.6152
No solution!

纯数学问题,直接引用上一段代码即可:

AC代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
double fab(double x)
{
    return x<=0?-x:x;
}
double fun(double x)
{
    return 8*x*x*x*x+7*x*x*x+2*x*x+3*x+6.0;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        double y,mid,left,right;;
        scanf("%lf",&y);
        if(y<fun(0)||y>807020306) printf("No solution!\n");
        else
        {
            left=0.0;right=100.0;
            while(fab(right-left)>=1e-10)
            {
                mid=0;
                mid=(left+right)/2;
                if(fab(fun(mid)-y)<=1e-10) break;
                else if(fun(mid)-y>0) right=mid;
                else left=mid;
            }
            printf("%.4lf\n",mid);
        }
    }
    return 0;
}

还有另一道相似的题:

Pie

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 6644    Accepted Submission(s): 2517

Problem Description

My birthday is coming up and traditionally I‘m serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This
should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though.

My friends are very annoying and if one of them gets a bigger piece than the others, they start complaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces, even if this leads to some pie getting spoiled (which is
better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size.

What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different.

Input

One line with a positive integer: the number of test cases. Then for each test case:

---One line with two integers N and F with 1 <= N, F <= 10 000: the number of pies and the number of friends.

---One line with N integers ri with 1 <= ri <= 10 000: the radii of the pies.

Output

For each test case, output one line with the largest possible volume V such that me and my friends can all get a pie piece of size V. The answer should be given as a floating point number with an absolute error of at most 10^(-3).

Sample Input

3
3 3
4 3 3
1 24
5
10 5
1 4 2 3 4 5 6 5 4 2

Sample Output

25.1327
3.1416
50.2655

      题目分析:

与上一道题基本相同,但是要判断的是蛋糕要分配的人数;( 一般二分的关键都在于终止条件的判断 )

还有一点,这道题比较坑的就是,再分配蛋糕的时候,也要考虑到自己;

所以输入人数后要people++;

AC代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define pi acos(-1.0)
double cake[10010];
double maxfun(int a,int b)
{
	return a>b?a:b;
}
int main()
{
	int c;
	scanf("%d",&c);
	while(c--)
	{
		int num,people;
		double r,max,sum,mid,left,right;
		sum=0.0;max=0.0;
		scanf("%d%d",&num,&people);
		people++;
		for(int i=1;	i<=num;	i++)
		{
			scanf("%lf",&r);
			cake[i]=pi*r*r;
			sum+=cake[i];
			max=maxfun(max,cake[i]);
		}
		left=max/people;right=sum/people;
		while(right-left>=0.000001)
		{
			int peoplenum=0;
			mid=(right+left)/2;
			for(int p=1;	p<=num;	p++)
				peoplenum+=(int)(cake[p]/mid);
			if(peoplenum<people) right=mid;
			else left=mid;
		}
		printf("%.4lf\n",left);
	}
	return 0;
}

在C++的STL中也提供了关于二分查找的一些函数,这里仅作介绍:

STL包含四种不同的二分查找算法:

binary_search

lower_bound

upper_bound

equal_range

只有在数据排序的情况下才可以做处理;

binary_search:在已排序的 [ left,right ) 中寻找元素path. 如果 [ left, right) 内有等于path的元素,它会返回true,否则返回false,它不返回查找位置。

lower_bound:它在已排序的 [ left,right )
中寻找元素path. 如果 [ left,right )
具有等于path的元素,lower_bound返回一个iterator指向其中第一个元素。如果没有这样的元素存在,它便返回假设这样的元素存在的话,会出现的位置。即指向第一个不小于path的元素。如果path大于
[ left,right ) 的任何一个元素,则返回last.

upper_bound:它在已排序的
[ left,right ) 中寻找path,返回可安插path的最后一个合适的位置。如果path存在,lower_bound 返回的是指向该元素的iterator。相较之下upper_bound并不这么做,它返回path可被安插的最后一个合适位置。如果path存在,那么它返回的iterator将指向path的下一个位置,而非path自身。

equal_range:返回值本质上结合了lower_bound和upper_bound两者的返回值。其返回值是一对iterator i 和 j , 其中i是path可安插的第一个位置,j则是path可安插的最后一个位置。可以推演出:[i,j)中的每个元素都等价于path,而且[i, j)是
[ left,right ) 之中符合上述性质的一个最大子区间。  算法lower_bound返回该range的第一个iterator, 算法upper_bound返回该range的past-the-end iterator,算法equal_range则是以pair的形式将两者都返回。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-02 18:16:07

Num 23 : HDOJ : 2199 Can you solve this equation? + HDOJ : 1969 Pie [ 二分法 ]的相关文章

hdoj 2199 Can you solve this equation?【浮点型数据二分】

Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 12766    Accepted Submission(s): 5696 Problem Description Now,given the equation 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y

hdoj 2199 Can you solve this equation? 【二分枚举】

题意:给出一个数让你求出等于这个数的x 策略:如题.因为整个式子是单调递增的,所以可以用二分. 要注意到精度. 代码: #include <stdio.h> #include <string.h> #include <math.h> #define eps 1e-10 #define f(x) 8*pow(x, 4) + 7*pow(x, 3) + 2*pow(x, 2) + 3*x int main() { int t; double n; scanf("%

hdu 2199 Can you solve this equation?

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2199 题目大意:找到满足8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y的x值,注意精确度问题. 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 5 using namespace std; 6 7 8 double fun(double s) 9 { 10 return

hdu 2199:Can you solve this equation?(二分搜索)

Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7493    Accepted Submission(s): 3484 Problem Description Now,given the equation 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,

hdu 2199 Can you solve this equation?(高精度二分)

http://acm.hdu.edu.cn/howproblem.php?pid=2199 Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 13468    Accepted Submission(s): 6006 Problem Description Now,given the

HDU 2199 Can you solve this equation?(二分精度)

HDU 2199 Can you solve this equation? 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. InputThe first line of the input contains an integer T(1<=T<=100) which means t

ACM:HDU 2199 Can you solve this equation? 解题报告 -二分、三分

Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16281 Accepted Submission(s): 7206 Problem Description Now,given the equation 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,can

HDU 2199 Can you solve this equation?【二分查找】

解题思路:给出一个方程 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,求方程的解. 首先判断方程是否有解,因为该函数在实数范围内是连续的,所以只需使y的值满足f(0)<=y<=f(100),就一定能找到该方程的解,否则就无解. 然后是求解过程, 假设一个区间[a,b],mid=(a+b)/2,如果f(a)*f(b)<0,那么函数f(x)在区间[a,b]至少存在一个零点,如果f(a)<0,说明0点在其右侧,那么将a的值更新为当前mid的值,如果f(a)&g

杭电 HDU ACM 2199 Can you solve this equation?

Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11180    Accepted Submission(s): 5151 Problem Description Now,given the equation 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 ==