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,&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