[A study notes pass] and two-thirds points

Summary

This section focuses on two-thirds of sub-issues, two points and three points when we usually distinguish between integer and floating point and processed differently.

Binary integer

The most classic of a class, we usually write

int L=... , R = ...;
while(R>L) {
    ...
    if(...) L=mid+1;
    else R=mid;
}
cout<<L (-1) <<endl;

Note that whether or not the final answer here L = mid + -1 depending on the switching of 1, mid is a legal solution. If so, -1 if not, output L.

Of course, there are some other wording, such as to the determination condition R> = L, the switch statement written L = mid + 1, r = mid-1, while the last recorded valid Ans. You can figure out one kind.

 

Binary floating-point number

Class binary floating point very easy, only need to pay attention to the error control precision.

Float-thirds


Trichotomy generally convex function is used to find the extreme value (although theoretically half derivative function is also very good), this time the need to use two mid values, i.e., m1 and M2, respectively, corresponding to the interval [l, r] of the two trisection point trisection two points is calculated, and then the left end point as required to shrink the left trisection point, or a right end point to the right trisection condensing point, so that the transfer can be performed. Achieved in the case of floating-point numbers is very easy.

 

Integer-thirds

Sometimes we need three points to an integer, we need to pay attention to the problem of rounding errors, reference worded as follows.

int l=..., r=...;
while(r>l){
    int m1=(2*l+r)/3, m2=(2*r+l+2)/3;
    if(...) r=m2-1;
    else l=m1+1;
}
cout<<l<<endl;

 

Half + authentication answer

If the function of the decisive answer to the question of non-parametric strictly monotonic, we can use half of it to be converted into a number of problem determination, which in dealing with many problems to be very effective.

 

Binary set of two points / thirds third set

When there are multiple variables decisive parameter, and the function partial derivative for each parameter variables are constant non-positive or non-negative constant, we can use both sets of half-half to solve the problem. Namely f (x, y), we first half of an x, it is converted to f (x, y) = g (y), and obtains g (y) of the answer, we get f (x, y) the answer on this x.

 

 

LOJ10011. "1.2 cases through a 1" angry cow

#include <bits/stdc++.h>
using namespace std;
int n,m,a[1000005];
int main() {
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+n+1);
    int l=0,r=1e+9;
    while(r>l) {
        int mid = (l+r)/2;
        int las = -1e+9, cnt = 0;
        for(int i=1;i<=n;i++)
            if(a[i]-las >= mid)
                ++cnt, las = a[i];
        if(cnt>=m) l=mid+1;
        else r=mid;
    }
    cout<<l-1<<endl;
}

LOJ10012. "1.2 cases through a 2" Best Cow Fences

A common trick involves half the answer, that fraction form, such as here ans = (sum (...)) / (sum (1)), we are half a ans, then inequality ans> (sum (.. .)) / (sum (1)) can be converted into sum (a [i] -ans)> 0, the maximum value of the processing by the suffix click on it.

Float question must pay attention to compensate for rounding errors.

#include <bits/stdc++.h>
using namespace std;

int n,l,a[1000005];
double s[1000005];

int main() {
    cin>>n>>l;
    for(int i=1;i<=n;i++) cin>>a[i];
    double L=0, R = 1e+9;
    while(R-L > 1e-6) {
        double mid = (L+R) / 2.0;
        for(int i=1;i<=n;i++)
            s[i] = s[i-1] + a[i] - mid;
        int flag = 0;
        s[n+1] = -1e+19;
        for(int i=n-l;i>=0;--i)
            s[i+l] = max(s[i+l], s[i+l+1]),
            flag |= (s[i+l]-s[i]>-1e-6);
        if(flag) L=mid;
        else R=mid;
    }
    cout<<(int)(L*1000.0+0.005)<<endl;
}

 

# 10013. "1.2 cases through a 3" curve

#include <bits/stdc++.h>
using namespace std;

int T,n;
double a[10005],b[10005],c[10005],t1,t2,t3;

double f(double x) {
    double ret = -1e+18;
    for(int i=1;i<=n;i++)
        ret = max(ret, a[i]*x*x+b[i]*x+c[i]);
    return ret;
}

int main() {
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--) {
        cin>>n;
        double ans = -1e+18;
        for(int i=1;i<=n;i++)
            cin>>a[i]>>b[i]>>c[i];
        double l=0,r=1000;
        while(r-l > 1e-11) {
            double m1 = l + (r-l)/3.0, m2 = r - (r-l)/3.0;
            if(f(m1)>f(m2)) l=m1;
            else r=m2;
        }

        cout<<setiosflags(ios::fixed)<<setprecision(4)<<f(l)<<endl;
    }
}

 

# 10014. "A practice through 1.2 1" series segmentation II

#include <bits/stdc++.h>
using namespace std;

int n,m,a[1000005];

int main() {
    cin>>n>>m;
    int mx=0;
    for(int i=1;i<=n;i++) cin>>a[i], mx=max(mx,a[i]);
    int l=mx,r=1e+9;
    while(r-l>0) {
        int mid = (l+r)/2;
        int sum = 0, cnt = 1;
        for(int i=1;i<=n;i++) {
            if(sum+a[i]>mid) ++cnt,sum=0;
            sum+=a[i];
        }
        if(cnt<=m) r=mid;
        else l=mid+1;
    }
    cout<<l<<endl;
}

# 10015. "1.2 Exercise 2 through a" proliferation

Dichotomous answer after considering how to test, to see whether violence enumeration point directly connected to disjoint-set to maintain connectivity.

#include <bits/stdc++.h>
using namespace std;

int n,x[100005],y[100005],f[105];

int find(int x) {
    return (f[x]==x)?x:(f[x]=find(f[x]));
}

int dis(int x1,int y1,int x2,int y2) {
    return abs(x1-x2) + abs(y1-y2);
}

int main() {
    cin>>n;
    for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
    int l=0,r=1e+9;
    while(r-l) {
        int mid = (l+r)/2, cnt = n;
        for(int i=1;i<=n;i++) f[i]=i;
        for(int i=1;i<=n;i++)
            for(int j=1;j<i;j++)
                if(dis(x[i],y[i],x[j],y[j])<=2*mid)
                    if(find(i)!=find(j)) f[find(i)]=find(j), --cnt;
        if(cnt==1) r=mid;
        else l=mid+1;
    }
    cout<<l<<endl;
}

# 10016. "1.2 Exercise 3 through a" light bulb

Geometric push formula

#include <bits/stdc++.h>
using namespace std;

int T; double H,h,D;

double f(double x) {
    double ret = h/(H-h)*x;
    if(ret+x > D)
        ret = D - x + (ret+x - D) * (H-h) / x;
    return ret;
}

int main() {
    cin>>T;
    while(T--) {
        cin>>H>>h>>D;
        double L=0,R=D;
        while(R-L > 1e-8) {
            double m1 = L + (R-L)/3, m2 = R - (R-L)/3;
            if(f(m1)>f(m2)) R=m2;
            else L=m1;
        }
        cout<<setiosflags(ios::fixed)<<setprecision(3)<<f(L)<<endl;
    }
}

# 10017. "1.2 Exercise 4 through a" conveyor belt

Third third sets, provided two ratios k, u.

#include <bits/stdc++.h>
using namespace std;

double ax,ay,bx,by,cx,cy,dx,dy,p,q,r;

double f(double x1,double y1,double x2,double y2) {
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

double calc(double k,double u) {
    double x1=k*ax+(1-k)*bx, y1=k*ay+(1-k)*by;
    double x2=u*cx+(1-u)*dx, y2=u*cy+(1-u)*dy;
    return f(ax,ay,x1,y1)/p+f(x1,y1,x2,y2)/r+f(x2,y2,dx,dy)/q;
}

double inner(double m) {
    double L=0,R=1;
    while(R-L > 1e-8) {
        double m1=L+(R-L)/3, m2=R-(R-L)/3;
        if(calc(m,m1)<calc(m,m2)) R=m2;
        else L=m1;
    }
    return calc(m,L);
}

int main() {
    cin>>ax>>ay>>bx>>by>>cx>>cy>>dx>>dy>>p>>q>>r;
    double L=0,R=1;
    while(R-L > 1e-8) {
        double m1=L+(R-L)/3, m2=R-(R-L)/3;
        if(inner(m1)<inner(m2)) R=m2;
        else L=m1;
    }
    cout<<setiosflags(ios::fixed)<<setprecision(2)<<inner(L)<<endl;
}

 

#include <bits/stdc++.h>using namespace std;
double ax,ay,bx,by,cx,cy,dx,dy,p,q,r;
double f(double x1,double y1,double x2,double y2) {    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
double calc(double k,double u) {    double x1=k*ax+(1-k)*bx, y1=k*ay+(1-k)*by;    double x2=u*cx+(1-u)*dx, y2=u*cy+(1-u)*dy;    return f(ax,ay,x1,y1)/p+f(x1,y1,x2,y2)/r+f(x2,y2,dx,dy)/q;}
double inner(double m) {    double L=0,R=1;    while(R-L > 1e-8) {        double m1=L+(R-L)/3, m2=R-(R-L)/3;        if(calc(m,m1)<calc(m,m2)) R=m2;        else L=m1;    }    return calc(m,L);}
int main() {    cin>>ax>>ay>>bx>>by>>cx>>cy>>dx>>dy>>p>>q>>r;    double L=0,R=1;    while(R-L > 1e-8) {        double m1=L+(R-L)/3, m2=R-(R-L)/3;        if(inner(m1)<inner(m2)) R=m2;        else L=m1;    }    cout<<setiosflags(ios::fixed)<<setprecision(2)<<inner(L)<<endl;}

 

Guess you like

Origin www.cnblogs.com/mollnn/p/11583991.html
Recommended