[] Data structure and algorithm study notes - "algorithm notes" -14 efficient techniques and algorithms [other]

By meter

As calculated in advance the Fibonacci sequence, and then query them when needed.

Utilize recursive

For example, it relates to a class of the subject sequence, it is necessary to calculate each bit value can be added to the sequence obtained by the calculated result of the right and left sides Qiu, it can be considered "left and right sides of the results of" whether a so-called by pushing pretreatment obtained, so that the latter may not be necessary to use repeatedly solved
example:

Given the string, ask how many total PAT can be formed?
Sample input
APPAPT
sample output
Hint: input string length does not exceed 10 . 5 , may be relatively large as a result of it only outputs a result of taking a remainder 1000000007.

The main idea of
direct violence timeout.
Here Insert Picture DescriptionHere Insert Picture Description

#include "stdafx.h"
#include <cstdio>

const int maxn = 100010;
const int MOD = 1000000007;

int main()
{
	char input[maxn];
	int num_of_p[maxn] = { 0 };
	int num_of_t = 0;
	int count_of_a = 0;
	int count_of_pat = 0;
	int len;
	scanf("%s", input);
	len = sizeof(input);
	for (int i = 0; i < len; i++)
	{
		if (input[i] == 'P')
			num_of_p[count_of_a]++;
		if (input[i] == 'A')
		{
			count_of_a++;
			num_of_p[count_of_a] = num_of_p[count_of_a - 1];
		}
	}
	int a_id = count_of_a;
	for (int i = len - 1; i >= 0; i--)
	{
		if (input[i] == 'T')
		{
			num_of_t++;
		}
		if (input[i] == 'A')
		{
			count_of_pat = (count_of_pat + num_of_p[--a_id] * num_of_t) % MOD;
		}
	}
	printf("%d\n", count_of_pat);
	return 0;
}

This question is very interesting ideas to solve problems, it is worth a closer look.

Random selection algorithm

It focuses on the question: how (assuming that the array number varies) large number of K obtained from the array in a disordered. The principle of random selection algorithm is similar to random quick sort algorithm , code is as follows:

void swap(int num[], int a, int b)
{
	int temp = num[a];
	num[a] = num[b];
	num[b] = temp;
	//return;
}

int randPartition(int A[], int left, int right)
{
	//生成[left,right]内的随机数p
	int p = (round(1.0*rand() / RAND_MAX * (right - left) + left));
	swap(A, left, p);
	//
	int temp = A[left];
	while (left < right)
	{
		while (left < right&&A[right] >= temp)	right--;
		A[left] = A[right]; 
		while (left < right&&A[left] < temp)	left++;
		A[right] = A[left];
	}
	A[left] = temp;
	return left;
}

//随机选择算法,从A[left,right]中返回第K大的数
int randSelect(int A[], int left, int right, int K)
{
	//这一步边界很重要,不要忘记了
	if (left == right)	return A[left];//边界   
	int p = randPartition(A, left, right);//划分主元后的位置p
	int M = p - left + 1;//A[p]是A[left,right]中的第M大
	if (M == K)	return A[p];
	if (M > K)
		return randSelect(A, left, p - 1, K);
	if (M < K)
		return randSelect(A, p + 1, right, K - M);
}

Application of a random selection algorithm:

For a given set of integers, a set of integers vary, it is divided into two subsets now want, and that both their own and the original set of cross-empty set, while in the two subsets the number of elements of n1 n2 of the absolute value of the difference | n1-n2 | premise as small as possible, the requirements of their respective elements of the S1 and S2 and the difference in absolute value of | S1-S2 | as large as possible. Seek | S1-S2 |.

In fact, n / 2-seeking set of larger elements, while according to the number of the set into two parts

#include "stdafx.h"
#include <cstdio> 
#include <time.h>
#include<stdlib.h>
#include<math.h>

const int maxn = 100010;
const int MOD = 1000000007;
int num[maxn], n;


void swap(int num[], int a, int b)
{
	int temp = num[a];
	num[a] = num[b];
	num[b] = temp;
	//return;
}

int randPartition(int num[], int left, int right)
{
	int p = round((1.0*rand() / RAND_MAX)*(right - left) + left);
	swap(num, p, left);
	int temp = num[left];
	while (left < right)
	{
		while (left<right&&num[right]>temp)	right--;
		num[left] = num[right];
		while (left<right&&num[left]<=temp)	left++;
		num[right] = num[left];
	}
	num[left] = temp;
	return left;
}

void randSelect(int num[], int left, int right, int K)
{
	srand((unsigned)time(NULL));
	if (left == right)	return;
	int p = randPartition(num, left, right);
	int M = p - left + 1;
	if (M == K)	return;
	if (M >= K)	randSelect(num, left, p - 1, K);
	if (M < K)	randSelect(num, p + 1, right, K - M);
}

int main()
{
	srand((unsigned)time(NULL));
	int sum = 0, sum1 = 0;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &num[i]);
		sum += num[i];
	}
	randSelect(num, 0, n - 1, n / 2);//n-1!!!!!!!
	for (int i = 0; i < n / 2; i++)
	{
		sum1 += num[i];
	}
	printf("%d\n", (sum - sum1) - sum1);
	return 0;
}

exercise:

K-seeking large number

Given a length of n (1≤n≤1,000,000) disordered sequence of positive integers, and another number k (1≤k≤1,000,000) (about the k-th largest numbers: {1,2,3,4 sequence e.g. 5, 6} in the third number is greater 4.)
input
of the first line of two positive integers m, n.
The second line of n positive integers.
Output
k-th largest number.
Sample input
. 6. 3
. 1. 3 2 4. 5. 6
Sample Output
4

#include <cstdio>
 #include <time.h>
 #include<stdlib.h>
#include<math.h>
//#include <vector>
//#include <cstring>
//#include <iostream>
//#include <string>
//#include <algorithm>

//using namespace std;
const int maxn = 100010;
const int MOD = 1000000007;
int num[maxn], n, k;


void swap(int num[], int a, int b)
{
	int temp = num[a];
	num[a] = num[b];
	num[b] = temp;
	//return;
}

int randPartition(int num[], int left, int right)
{
	int p = round((1.0*rand() / RAND_MAX)*(right - left) + left);
	swap(num, p, left);
	int temp = num[left];
	while (left < right)
	{
		while (left<right&&num[right]>temp)	right--;
		num[left] = num[right];
		while (left<right&&num[left]<=temp)	left++;
		num[right] = num[left];
	}
	num[left] = temp;
	return left;
}

void randSelect(int num[], int left, int right, int K)
{
	srand((unsigned)time(NULL));
	if (left == right)	return;
	int p = randPartition(num, left, right);
	int M = p - left + 1;
	if (M == K)	return;
	if (M >= K)	 randSelect(num, left, p - 1, K);
	if (M < K )	 randSelect(num, p + 1, right, K - M);
}

int main()
{
	srand((unsigned)time(NULL));
	while (scanf("%d%d", &n, &k) != EOF)
	{
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &num[i]);
		}
		randSelect(num, 0, n - 1, n-k+1);//n-1!!!!!!!
		printf("%d\n", num[n-k]);//n-k!!!
	}
		return 0;
}
Published 43 original articles · won praise 4 · Views 1209

Guess you like

Origin blog.csdn.net/weixin_42176221/article/details/101788562