Program design final exam review topic four: linear structure

The fourth topic is: Linear Data Structure

There are many linear data structures: one-dimensional arrays, pointers, stacks, queues, and some data structures defined in STL, and so on. These linear structures are also useful in solving some problems. One-dimensional arrays, everyone knows that there is a fixed length, there are subscripts, and the position of each subscript corresponds to a value; pointers can also be regarded as one-dimensional arrays; the stack is a data structure that comes out first; Data structures, etc.

There is nothing to write about this topic, only to make a question, use these linear data structures to complete some questions.

1. Largest Rectangle in a Histogram (HDU 1506:https://vjudge.net/problem/HDU-1506 )

Topic: Find the area of ​​the largest rectangle that can be formed by a group of rectangles of adjacent unit width.

As shown in the figure: the largest rectangular area in the rectangular set on the left is the shaded part on the right.

It is required to find the area of ​​this shaded part.

Problem Solution: It can be seen that the width of these rectangles is the same, so we can imagine a "merger" method for the maximum area after combination. Any rectangle in any position can "engage" the rectangle around it higher than it, and stop in front of the rectangle lower than it. Then the height of this rectangle is multiplied by the total number of "merged" rectangles, which is the maximum area that this rectangle can expand. This way we can find the maximum rectangular area.

The specific implemented data structure may be a monotonic stack.

Turned into another small problem: find the position of the first element on the left and right in a one-dimensional array that is smaller than it. The pseudo code of the algorithm is: traverse the array from left to right, and the top of the stack is the index of the smallest element in the traversal process. Because, the element to the right and the smaller is always the element on the left that is larger than it is the position of the element that is later found to the left and is smaller than the current element.

stack Stack s, the subscript of each element is stored. The L [i] array is used to store each element smaller than its left. For the array a [].

for :i->n

    while (stack is not empty && the top element of the stack should be no less than the current element)

         Pop the top element of the stack

   if (stack empty)

     L [i] = 0 (recording the smaller element on the left is 0)

   else L [i] = top of stack

   The current element is indexed onto the stack.

Code used to solve the problem:

#include<iostream>
#include<stack>
using namespace std;

long long a[100005];
struct cfx
{
	int l;
	int r;
};

int main()
{
	int n;
	while(cin>>n)
	{
		if(n==0) break;
		long long ans=0;
		cfx dis[100005]; 
		for(int i=1;i<=n;i++)
		    cin>>a[i];
		stack<int> s;
		for(int i=1;i<=n;i++)
		{
			while(!s.empty()&&a[s.top()]>=a[i])
			    s.pop();
			if(s.empty())
			    dis[i].l=0;
			else dis[i].l=s.top();
			s.push(i);
		}
		stack<int> k;
		for(int i=n;i>=1;i--)
		{
			while(!k.empty()&&a[k.top()]>=a[i])
			    k.pop();
			if(k.empty())
			    dis[i].r=n+1;
			else dis[i].r=k.top();
			k.push(i);
		}
		for(int i=1;i<=n;i++)
		{
			if((dis[i].r-dis[i].l-1)*a[i] > ans)
			    ans=(dis[i].r-dis[i].l-1)*a[i];
		}
		cout<<ans<<endl;
	}
	return 0;
}

There are two parts in the middle that use the monotonic stack to solve the problem, one is to look to the left, and the other is to look to the right.

Finally, a subtraction can be used to find the length to find the area.

2.Jessica‘s Reading Problem (poj3320)

Jessica wants to read a book, this book has p pages, page i happens to have a knowledge point ai (each knowledge point has a different number). The knowledge points in the whole book may be mentioned many times. Before the exam, she will review all the knowledge points.

This question uses a linear data structure is a one-dimensional array, the method used is the ruler method.

My understanding of ruler method: define a segment from this sequence, this "segment" has a start node and an end node. During initialization, the start node is equal to the end node. By continuously moving the end node, it is determined whether this segment is already in line with the requirements. If it is, then the start node is moved until the end node reaches the end of the sequence. The state of these "segments" is used to judge a most consistent result.

The AC code at the time (may be a bit redundant):

#include<cstdio>
#include<iostream>
#include<map>
#include<set>
#pragma   warning(disable:4996)
using namespace std;
int min(int a, int b)
{
	return a < b ? a : b;
}
int main()
{
	int P;
	while (cin >> P)
	{
		set<int> se;
		int *a = new int[P + 1];

		for (int i = 0; i < P; i++)
		{
			scanf("%d", &a[i]);
			se.insert(a[i]);
		}
			
		int n = 0;
		int cnt = se.size();
		/*for (int i = 1; i < P; i++)
		{
			for (int j = 0; j < i; j++)
			{
				if (a[j] == a[i])
				{
					cnt--;
					break;
				}
			}
		}*/
		//cout << cnt << endl;
		int s = 0, t = 0, num = 0;
		map <int, int> count;
		int ans = P;
		for (;;)
		{
			while (t < P&&num < cnt)
			{
				if (count[a[t]] == 0)
				{
					num++;
				}
				count[a[t]]++;
				t++;
			}
			if (num < cnt) break;
			ans = min(ans, t - s);
			count[a[s]]--;
			if (count[a[s]] == 0)
			{
				num--;
			}
			s++;
		}
		delete[]a;
		cout << ans << endl;
	}
	
	return 0;
}

For the above code, there are still a few points to be explained. First of all, the direct rule-taking algorithm is based on the seniors; the use of set is because the set-defined data structure has a useful function that can output the number of different elements in this sequence, that is, the number of knowledge points; then map It is to record the number of occurrences of each knowledge point.

Then the problem with this code is that the set took a long time to insert. . .

3. Sequence (poj3061) (second ruler method)

The sequence of length n has a0, a1, a2 ... an-1, and an integer S. Find the minimum value of the sum of consecutive subsequences in this sequence that is not less than the length of S. If the solution does not exist, 0 is output. E.g:

Sample Input

2
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5

Sample Output

2
3

Also using the ruler method, first initialize s = t = sum = 0; while (sum <S) then t ++, sum increases; if sum> = S cannot be satisfied, terminate, and update the minimum value to min (ans, ts ); If sum> = S is satisfied, then change ans and subtract as, and then enter the next judgment or increase t.

Specific code:

#include<iostream>
using namespace std;
int a[100005];
int min(int a,int b)
{
	return a<b?a:b;
}
int main()
{
	int t,n,S;
	cin>>t;
	while(t--)
	{
		cin>>n>>S;
		for(int i=0;i<n;i++)
		    cin>>a[i];
		int s=0,t=0,sum=0;
		int ans=n+1;
		while(true)
		{
			while(t<n&&sum<S)
			{
				sum+=a[t++];
			}
			if(sum<S) break;
			ans=min(ans,t-s);
			sum=sum-a[s];
			s++;
		}
		if(ans>n) ans=0;
		cout<<ans<<endl;	
	}
	return 0;
}

So much for linear structures. In fact, there are many, many useful linear structures in STL. What priority queues, set, map, pair, etc. have their own strengths.

Combining the above three questions, there are many algorithms that can be used on the linear structure, there are only two kinds above, and the individual compares the dishes (decided to work hard on this summer vacation ...). But having said that, the ruler method and the monotonic stack monotonous queue are both very useful methods for solving problems, and can greatly optimize the time complexity of your program when it is solved simply by brute force.

 

 

 

 

 

 

Published 6 original articles · liked 0 · visits 184

Guess you like

Origin blog.csdn.net/morning_zs202/article/details/92636428