https://vjudge.net/problem/HDU-2199
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.
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);
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.
2
100
-4
1.6152
No solution!
这题就是最简单的实数二分,原方程是单调的,直接二分求解即可,重点是学习一下实数二分的写法,
#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!\n");
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\n", mid);
}
return 0;
}
当精度过高可能进入死循环风险时,可以通过一个变量控制循环次数,比如100次就停止
https://vjudge.net/problem/POJ-2785
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 .
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 .
For each input file, your program has to write the number quadruplets whose sum is zero.
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
5
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
#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;
}
https://vjudge.net/problem/POJ-2456
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?
* Line 1: Two space-separated integers: N and C
* Lines 2..N+1: Line i+1 contains an integer stall location, xi
* Line 1: One integer: the largest minimum distance
5 3
1
2
8
4
9
3
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个奶牛。
#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;
}
思想同最大化最小值
此题有一定思维难度,单独写一篇题解,地址https://www.cnblogs.com/artoriax/p/10375508.html
这种类型的题目需要转换一下
此题有一定思维难度,单独写一篇题解,地址https://www.cnblogs.com/artoriax/p/10375709.html
https://vjudge.net/problem/HDU-2899
Now, here is a fuction:
F(x) = 6 * x^7+8x^6+7x^3+5x^2-yx (0 <= x <=100)
Can you find the minimum value when x is between 0 and 100.
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)
Just the minimum value (accurate up to 4 decimal places),when x is between 0 and 100.
2
100
200
-74.4291
-178.8534
函数的一项系数未知,给定这个系数的值,找出函数的极小值点x
三分模版题,每次舍弃离极值点远的部分
#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\n", calc(midl));
}
return 0;
}
原文:https://www.cnblogs.com/artoriax/p/10375773.html