The eighth chapter high efficient algorithm design

Source: Internet
Author: User

Divide and conquer the method to seek maximum continuous and

Note that the range is [x, y)

#include <bits/stdc++.h>using namespace Std;int maxsum (int *a,int x,int y) {    if (y-x==1) return a[x];    int m=x+ (Y-X)/2;    int maxs = max (Maxsum (a,x,m), Maxsum (A,m,y));    int v,l,r;    v=0; L=A[M-1];    for (int i=m-1;i>=x;i--) L=max (L,v+=a[i]);    v=0; R=A[M];    for (int i=m;i<y;i++) R=max (R,v+=a[i]);    Return Max (MAXS, l+r);} int main () {    int a[]={1,-1,2,3,-2};    printf ("%d\n", Maxsum (a,0,4));    return 0;}
Merge sort, note the range or [x, Y]

Merging is the sequence of sorting the smallest ranges first

Then merge, merge Purple book There is a picture, the idea is very clear

#include <bits/stdc++.h>using namespace std;void merge_sort (int *a,int x,int y,int *t) {    if (y-x>1) {        int m=x+ (Y-X)/2;        int p=x,q=m,i=x;        Merge_sort (a,x,m,t);        Merge_sort (a,m,y,t);        while (p<m| | Q<y) {            if (q>=y| | (P<m&&a[p]<=a[q])) t[i++]=a[p++];            else t[i++]=a[q++];        }        for (i=x;i<y;i++) a[i]=t[i];}    } int main () {    int a[]={0,2,1};    int t[100];    Merge_sort (a,0,3,t);    for (int i=0;i<3;i++) printf ("%d", A[i]);    return 0;}

Reverse order to the problem

The same divide-and-conquer method, using the merge sort from M forward sweep characteristics, to count the inverse logarithm

Because the sequence is ordered, the direct add (M-P) is

#include <bits/stdc++.h>using namespace Std;int cnt=0;void merge_sort (int *a,int x,int y,int *t) {    if (y-x>1 ) {        int m=x+ (y-x)/2;        int p=x,q=m,i=x;        Merge_sort (a,x,m,t);        Merge_sort (a,m,y,t);        while (p<m| | Q<y) {            if (q>=y| | (P<m&&a[p]<=a[q])) t[i++]=a[p++];            else {t[i++]=a[q++]; cnt+=m-p;}        }        for (int i=x;i<y;i++) a[i]=t[i];}    } int main () {    int a[]={0,2,1,-1,-3};    int t[100];    Merge_sort (a,0,5,t);    printf ("%d\n", CNT);    return 0;}

Quick sort:

Select a point from the starting point, sweep forward from the back, and then sweep back from the front

Pick the second point, you know, pick the last one.

#include <bits/stdc++.h>using namespace std;void quickSort (int a[],int left,int right) {    int i=left;    int j=right;    int Temp=a[left];    if (left >= right) return;    while (I!=J) {        while (i<j&&a[j]>=temp) j--;        if (j>i) a[i]=a[j];        while (i<j&&a[i]<temp) i++;        if (i<j) a[j]=a[i];    }    A[i]=temp;    QuickSort (a,left,i-1);    QuickSort (a,i+1,right);} int main () {    int a[]={0,2,1,-1,-3};    int t[100];    QuickSort (a,0,4);    for (int i=0;i<5;i++)    printf ("%d", A[i]);    return 0;}
Quick Selection Questions

According to the Mark Point after the fast sorting, determine if the k is greater than or less than the number of the sequence to be found, then the directional enumeration

#include <bits/stdc++.h>using namespace Std;int k=2;int quickSort (int a[],int left,int right) {    int i=left;    int j=right;    int Temp=a[left];    printf ("temp:%d   * \ n", A[left]);    if (left >= right) return 0;    while (I!=J) {        while (i<j&&a[j]>=temp) j--;        if (j>i) a[i]=a[j];        while (i<j&&a[i]<temp) i++;        if (i<j) a[j]=a[i];    }    for (int i=0;i<5;i++)    printf ("%d", a[i]); printf ("\ n");    A[i]=temp; printf ("i =%d\n", i);    if (k<i)    quickSort (a,left,i-1);    else if (k>i)    quickSort (a,i+1,right);    else return a[k];} int main () {    int a[]={0,2,1,-1,-3};// -3-1 0 1 2    int t[100];    k=0;    printf ("%d\n", QuickSort (a,0,4));    return 0;}
Binary Find binary find

Iterative implementations

#include <bits/stdc++.h>using namespace std;int bsearch (int *a,int x,int Y,int v) {    int m;    while (x<y) {        m=x+ (y-x)/2;        if (a[m]==v) return m;        else if (a[m]>v) y=m;        else x=m+1;    }    return-1;} int main () {    int a[]={0,2,1,-1,-3};// -3-1 0 1 2    int t[100];    Sort (a,a+5);    printf ("%d\n", bsearch (a,0,5,-3));    return 0;}
Two-point search for upper and lower bounds
There are also two functions in the STL that can be used directly
#include <bits/stdc++.h>using namespace Std;int lower_bound (int *a,int x,int Y,int v) {    int m;    while (x<y) {        m=x+ (y-x)/2;        if (a[m]>=v) y=m;        else x=m+1;    }    return x;} int upper_bound (int *a,int x,int Y,int v) {    int m;    while (x<y) {        m=x+ (y-x)/2;        if (a[m]<=v) x=m+1;        else y=m;    }    return y;} int main () {    int a[]={0,2,1,-1,-3,2};// -3-1 0 1 2    int t[100];    Sort (a,a+5);    printf ("%d\n", Lower_bound (a,0,5,2));    printf ("%d\n", Upper_bound (a,0,5,2));    return 0;}
Board coverage issues

Recursive division solution, boundary for K==1

#include <bits/stdc++.h>using namespace Std;int cnt=0;int merge_qipan (int k) {    if (k==1)  return ++cnt;    Merge_qipan (k-1);    Merge_qipan (k-1);    Merge_qipan (k-1);    Merge_qipan (k-1);    return ++cnt;} int main () {    int k;    scanf ("%d", &k);    printf ("%d\n", Merge_qipan (k));    return 0;}

Recurring schedule Problem: Can't get out

The Giant and the ghost: temporarily ignoring

Greedy method:

Optimal loading problem: pure greed

Partial knapsack problem: greedy by ratio

Interval-related issues: Select disjoint intervals, sort by B

The first type: A1>A2 Select A1 then: A1<a2<a3 from the front does not intersect the next selection

Interval pick problem: Sort by B, the first interval takes the last point

Interval coverage issues:

Pretreatment:

First cut off the parts outside [s,t]

Sort by a, starting point not s, no solution

Otherwise select the longest interval of the starting point s

Then the new starting point is the end of the previous interval

Huffman Code:

Sort the characters into table p, create a new node queue, 22 merges each time

Construction Method:

Example 8-1:UVA120 Pancake

The analysis of the book is very clear, in fact, is to find a workable solution, but do not know is not the best

This is called the construction algorithm, each time the biggest, the biggest automatic arranging will not have to tube

The problem is that it is really cumbersome to implement with arrays, see a 666 problem, a double-ended queue, and a reverse flip, notice that flipping is sequential.

#include <bits/stdc++.h>using namespace Std;int main () {for    (string strline;getline (Cin,strline);cout< < ' 0 ' <<endl) {        cout<<strline<<endl;        Istringstream ISS (strLine);        Deque<int> Stack;        for (int ndiam;iss>>ndiam; Stack.push_front (Ndiam));        For (Deque<int>::iterator I=stack.begin (); I!=stack.end (); i++) {            Deque<int>::iterator IMax = max_ Element (I,stack.end ());            if (IMAX! = i) {                if (imax! = Stack.end ()-1) {                    reverse (imax,stack.end ());                    Cout<<distance (Stack.begin (), IMax) + 1<< ";                }                Reverse (I,stack.end ());                Cout<<distance (Stack.begin (), i) +1<< ";}            }    }    return 0;}
Example 8-2 United Nations building UVa1605

Also according to the Purple book to give the idea, a total of two, the first layer with I put the country, the next layer by column, so that each first tier of the country and the second floor and each country is next to each other

Note that the state can only use uppercase and lowercase letters

#include <bits/stdc++.h>using namespace Std;int a[60][60];int b[60][60];int main () {    int n;    while (~SCANF ("%d", &n)) {        printf ("%d%d%d\n", 2,n,n);        for (int i=0;i<n;i++) for        (int j=0;j<n;j++) {            a[i][j]=i;            b[i][j]=j;        }        for (int i=0;i<n;i++) {        for (int j=0;j<n;j++) {            if (a[i][j]>25) printf ("%c", a[i][j]-26+ ' a ');            else            printf ("%c", a[i][j]+ ' a ');        }        printf ("\ n");        }        printf ("\ n");        for (int i=0;i<n;i++) {        for (int j=0;j<n;j++) {             if (b[i][j]>25) printf ("%c", b[i][j]-26+ ' a ');            else            printf ("%c", b[i][j]+ ' A ');        }        printf ("\ n");        }    printf ("\ n");    }    return 0;}
Midway encounter Method: Solve the problem from two directions, the final summary

8-3 UVa1152 and four values for 0

The hash of this question is very subtle and well understood.

#include <bits/stdc++.h>using namespace std;struct hashmap{    static const int mask = 0X7FFFFF;    int p[8388608],q[8388608];    void Clear ()    {for        (int i=0;i<=mask; + + i) q[i]=0;    }    int & operator [] (int k) {        int i;        For (i=k&mask; q[i]&&p[i]!=k;i= (i+1) &mask);            p[i]=k;        return q[i];}    } Hash;int Main () {    int t;    scanf ("%d", &t);    while (t--) {        hash.clear ();        int n,sum=0,a[4100],b[4100],c[4100],d[4100];        scanf ("%d", &n);        for (int i=0;i<n;i++) scanf ("%d%d%d%d", &a[i],&b[i],&c[i],&d[i]);        for (int i=0;i<n;i++) for            (int j=0;j<n;j++)            hash[a[i]+b[j]]++;        for (int. i=0;i<n;i++) for            (int j=0;j<n;j++)            sum+=hash[-(C[i]+d[j])];        printf ("%d\n", sum);        if (t) printf ("\ n");    }    return 0;}


Problem decomposition:

Example 8-4 legendary car UVa11134

Similar to the above-mentioned interval related problems, first the graph is divided into two one-dimensional axis, and then according to the given interval, according to B sort, from the front to find the position of I, to find the correct

#include <bits/stdc++.h>using namespace std;struct pp {int x1,x2,y1,y2,x,y,num;} B[5050];bool CMP1 (pp a,pp b) {if (a.x2==b.x2) return a.x1<b.x1; else return a.x2<b.x2;} BOOL Cmp2 (pp a,pp b) {if (a.y2==b.y2) return a.y1<b.y1; else return a.y2<b.y2;} BOOL Cmp3 (pp a,pp b) {return a.num<b.num;}    int main () {int n; while (scanf ("%d", &n) &&n) {for (int i=0;i<n;i++) {scanf ("%d%d%d%d", &b[i].x1,&b[i].y1,&b[ I].X2,&AMP;B[I].Y2); b[i].x=0; b[i].y=0; b[i].num=i+1;        } sort (B,B+N,CMP1);//for (int i=0;i<n;i++) printf ("%d%d%d%d\n", b[i].x1,b[i].y1,b[i].x2,b[i].y2);        int aa=0,bb=0; for (int i=1;i<=n;i++) for (int j=0;j<n;j++) {if (b[j].x1<=i &&b[j].x2>=i &&!b  [j].x) {b[j].x=i; aa++;            Break }} sort (B,B+N,CMP2);//for (int i=0;i<n;i++) printf ("%d%d%d%d\n", b[i].x1,b[i].y1,b[i].x2,b[i].y        2); for (int i=1;i<=n;i++) for (int j=0;j<n;j++) {if (b[j].y1<=i &&b[j].y2>=i &&!  B[J].Y) {b[j].y=i; bb++;            Break }} if (Aa==n&&bb==n) {sort (B,b+n,cmp3); for (int i=0;i<n;i++) printf ("%d%d\n", b[i].x,b        [I].Y];    } else printf ("impossible\n"); } return 0;}


Equivalent conversion

Example 8-5 UVa11054 Wine Trading

Equivalent conversion is every time only to consider how much Labor A2 home winery to the A1 home wine, the result is the best

#include <bits/stdc++.h>using namespace Std;int main () {    int n;while (cin>>n&&n) {        int ans= 0,a,last=0;        for (int. i=0;i<n;i++)        {cin>>a;ans+=abs (last); last+=a;}        Cout<<ans<<endl;} return 0;}

Scanning method: To maintain some important quantities and simplify the calculation when the sweep surface method is re-enumerated

Example 8-6 UVa1606 of sexual parentage

This question of the polar sort does not

#include <bits/stdc++.h>using namespace std;struct node{public:int x, y, Z;    Double rad;    BOOL operator < (const node& RHS) Const {return rad < Rhs.rad; }}c[1000],d[1000];bool Turn (node&a,node&b) {return a.x*b.y>=a.y*b.x;}    int main () {int N; while (~SCANF ("%d", &n) &&n) {for (int i=0;i<n;i++) scanf ("%d%d%d", &c[i].x,&c[i].y,&c[i].z        );        if (n<=2) {printf ("%d\n", N); continue;}        int maxn=0;            for (int i=0;i<n;i++) {int k=0;                    for (int j=0;j<n;j++) {if (i!=j) {d[k].x = c[j].x-c[i].x;                    D[k].y = C[J].Y-C[I].Y;                        if (c[j].z) {d[k].x =-d[k].x;                    D[k].y =-D[K].Y;                    } D[k].rad = atan2 (d[k].y,d[k].x);                k++;            }} sort (d,d+k);            int L=0;int Ans=1;int r=0; WHile (l<k) {if (l==r) {r= (r+1)%k; ans++; } while (L!=r&&turn (D[l],d[r])) {ans++;                R= (r+1)%k; } MAXN = max (Maxn,ans); l++;            ans--;    }} printf ("%d\n", MAXN); } return 0;}


Window Sliding method

Example 8-7 the only snowflake UVa11572

In fact, it is a convenient loop, but according to test instructions if you encounter the number of repetitions with the current sequence, you need to find the duplicate number from the front and then delete

Record the maximum sequence length each time, conveniently over, the result, the following two implementations, a set, a map

#include <bits/stdc++.h>using namespace Std;const int maxn = 1e6 + 5;int b[maxn];int main () {    int t,n;    scanf ("%d", &t);    while (t--) {        scanf ("%d", &n);        for (int i=0;i<n;i++) scanf ("%d", &b[i]);        set<int> s;        int l=0,r=0,ans=0;        while (R<n) {            while (R<n&&!s.count (B[r])) {S.insert (b[r]); r++; }            Ans=max (ans,r-l);            S.erase (b[l++]);        }        printf ("%d\n", ans);    }    return 0;}
Calculates the last array of positions of the same number with a map

#include <bits/stdc++.h>using namespace Std;const int maxn = 1e6 + 5;int a[maxn],last[maxn];map<int,int > cur; int main () {    int t,n;    scanf ("%d", &t);    while (t--) {        scanf ("%d", &n);        Cur.clear ();        for (int i=0;i<n;i++) {            scanf ("%d", &a[i]);            if (!cur.count (a[i))) Last[i]=-1;            else last[i]=cur[A[i]];            cur[A[i]]=i;        }        int l=0,r=0,ans=0;        while (R<n) {            while (r<n&&last[r]<l) r++;            Ans=max (ans,r-l);            l++;        }        printf ("%d\n", ans);    }    return 0;}

Using Data structures:

Improve operational efficiency without changing the main algorithm

The minimum value of f (i) I to K, required F (1) ... f (n-k+1)


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

The eighth chapter high efficient algorithm design

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.