zoukankan      html  css  js  c++  java
  • 二分三分

    实数二分

    例题 HDU-2199 Can you solve this equation?

    题目链接

    https://vjudge.net/problem/HDU-2199

    题面

    Description

    Now,given the equation 8x^4 + 7x^3 + 2x^2 + 3x + 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 <bits/stdc++.h>
    #define eps 1e-8//使用eps控制精度,越小循环次数也就越多
    using namespace std;
    double y;
    double calc(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--) {
    		scanf("%lf", &y);
    		if (y < calc(0) || y > calc(100)) {
    			printf("No solution!
    ");
    			continue;
    		}
    		double l = 0, r = 100;
    		double mid;
    		while (r - l > eps) {//循环条件注意是r-l>eps
    			mid = (r + l) / 2;
    			if (calc(mid) > y) r = mid;//注意这里是直接等于mid
    			else l = mid;
    		}
    		printf("%.4f
    ", mid);
    	}
    	return 0;
    }
    
    

    注意

    当精度过高可能进入死循环风险时,可以通过一个变量控制循环次数,比如100次就停止

    整数二分

    例题 POJ-2785 4 Values whose Sum is 0

    题目链接

    https://vjudge.net/problem/POJ-2785

    题面

    Description

    The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

    Input

    The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 2 28 ) that belong respectively to A, B, C and D .

    Output

    For each input file, your program has to write the number quadruplets whose sum is zero.

    Sample Input

    6
    -45 22 42 -16
    -41 -27 56 30
    -36 53 -37 77
    -36 30 -75 -46
    26 -38 -10 62
    -32 -54 -6 45
    

    Sample Output

    5
    

    Hint

    Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).

    题解

    简述一下题意,找到有多少对(a,b,c,d)满足a+b+c+d=0。

    n为4000,(n^3logn)枚举前三个的和二分最后一个肯定会超时,那就预处理a+b的和,二分c+d的和即可,复杂度(2n^2logn)可以AC,预处理可以直接用一个multiset处理,(upper\_bound-lower\_bound)即为答案要加上的个数,因为如果没有正好相等的数upper_bound返回的地址刚好等于lower_bound

    AC代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define N 4005
    using namespace std;
    int a[N], b[N], c[N], d[N];
    int sum[N * N];
    int main() {
    	int n;
    	while (scanf("%d", &n) != EOF) {
    		for (int i = 1; i <= n; i++) {
    			scanf("%d%d%d%d", &a[i], &b[i], &c[i], &d[i]);
    		}
    		int cnt = 0;
    		for (int i = 1; i <= n; i++) {
    			for (int j = 1; j <= n; j++) {
    				sum[++cnt] = a[i] + b[j];
    			}
    		}
    		sort (sum + 1, sum + cnt + 1);
    		long long ans = 0;
    		for (int i = 1; i <= n; i++) {
    			for (int j = 1; j <= n; j++) {
    				int x = -(c[i] + d[j]);
    				ans += upper_bound(sum + 1, sum + cnt + 1, x) - lower_bound(sum + 1, sum + cnt + 1, x); 
    			}
    		}
    		cout << ans << endl;
    	}
    	return 0;
    }
    
    

    二分答案

    类型一:最大化最小值

    例题 POJ-2456 Aggressive cows

    题目链接

    https://vjudge.net/problem/POJ-2456

    题面

    Description

    Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000).

    His C (2 <= C <= N) cows don't like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?

    Input

    * Line 1: Two space-separated integers: N and C

    * Lines 2..N+1: Line i+1 contains an integer stall location, xi

    Output

    * Line 1: One integer: the largest minimum distance

    Sample Input
    5 3
    1
    2
    8
    4
    9
    
    Sample Output
    3
    
    Hint

    OUTPUT DETAILS:

    FJ can put his 3 cows in the stalls at positions 1, 4 and 8, resulting in a minimum distance of 3.

    Huge input data,scanf is recommended.

    题解

    看到最大化最小值或者最小化最大值,基本都是二分答案的思想,即先二分知道了答案,再判断这个答案是否可行,可行就向右(左)二分找新的答案继续判断,这个题也是这样,先对奶牛的位置排序,二分奶牛之间的距离,如果这头奶牛距离上一次安放的奶牛大于二分的距离就放上,看最后是否放够了C个奶牛。

    AC代码
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define N 100050
    using namespace std;
    typedef long long ll;
    ll a[N];
    int n, c;
    bool check(ll x) {
    	ll pos = a[1];
    	int tmp = c;
    	tmp--;
    	for (int i = 2; i <= n; i++) {
    		if (a[i] >= pos + x) {
    			pos = a[i];
    			if (tmp > 0) tmp--;
    			if (tmp == 0) break;
    		}
    	}
    	return tmp == 0;
    }
    int main() {
    	scanf("%d%d", &n, &c);
    	for (int i = 1; i <= n; i++) {
    		scanf("%lld", &a[i]);
    	}
    	sort (a + 1, a + n + 1);
    	ll l = 0, r = 1000000050;
    	ll mid;
    	ll ans = 0;
    	while (l <= r) {
    		mid = (l + r) >> 1;
    		if (check(mid)) {
    			ans = max(ans, mid);
    			l = mid + 1;
    		}
    		else {
    			r = mid - 1;
    		}
    	}
    	cout << ans << endl;
    	return 0;
    }
    
    

    类型二:最小化最大值

    思想同最大化最小值

    例题 POJ-3104 Drying

    此题有一定思维难度,单独写一篇题解,地址https://www.cnblogs.com/artoriax/p/10375508.html

    类型三:最大化平均值

    这种类型的题目需要转换一下

    例题 POJ-3111 K Best

    此题有一定思维难度,单独写一篇题解,地址https://www.cnblogs.com/artoriax/p/10375709.html

    三分

    例题 HDU-2899 Strange fuction

    题目链接

    https://vjudge.net/problem/HDU-2899

    题面

    Description

    Now, here is a fuction:
    F(x) = 6 * x7+8*x6+7x3+5*x2-yx (0 <= x <=100)
    Can you find the minimum value when x is between 0 and 100.

    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 only one real numbers Y.(0 < Y <1e10)

    Output

    Just the minimum value (accurate up to 4 decimal places),when x is between 0 and 100.

    Sample Input

    2
    100
    200
    

    Sample Output

    -74.4291
    -178.8534
    

    题意

    函数的一项系数未知,给定这个系数的值,找出函数的极小值点x

    题解

    三分模版题,每次舍弃离极值点远的部分

    AC代码

    #include<bits/stdc++.h>
    #define eps 1e-8
    using namespace std;
    double y;
    double calc(double x) {
    	return 6 * pow(x, 7) + 8 * pow(x, 6) + 7 * pow(x, 3) + 5 * x * x - y * x;
    }
    int main() {
    	int t;
    	scanf("%d", &t);
    	while (t--) {
    		scanf("%lf", &y);
    		double l = 0, r = 100;
    		double midl, midr;
    		while (r - l > eps) {
    			midl = (l + r) / 2;
    			midr = (midl + r) / 2;
    			double cmidl = calc(midl);
    			double cmidr = calc(midr);
    			if (cmidl < cmidr) {
    				r = midr;
    			}
    			else l = midl;
    		}
    		printf("%.4f
    ", calc(midl));
    	}
    	return 0;
    }
    
  • 相关阅读:
    正能量
    战略定位
    市场营销
    品牌营销
    CSS3圆角,阴影,透明
    iOS开发的22个奇谲巧技
    [设计模式] javascript 之 策略模式
    让网站和APP更具动感的几点建议
    JAVASCRIPT 之escape 介绍
    CSS2.0中最常用的18条技巧
  • 原文地址:https://www.cnblogs.com/artoriax/p/10375773.html
Copyright © 2011-2022 走看看