[] Estructura de datos y estudio algoritmo de notas - "notas" -14 algoritmo técnicas y algoritmos eficientes [otra]

juego de mesa

Como se calcula de antemano la secuencia de Fibonacci, y luego consultar cuando sea necesario.

utilizar recursiva

Por ejemplo, se refiere a una clase de la secuencia sujeto, es necesario calcular cada valor de bit puede ser añadido a la secuencia obtenida por el resultado calculado de los lados derecho e izquierdo Qiu, se puede considerar "lados izquierdo y derecho de los resultados de" si una de las llamadas empujando pretratamiento obtuvieron, de manera que éste puede no ser necesario utilizar resuelto repetidamente
ejemplo:

Dada la cadena, preguntar cuántos PAT totales se pueden formar?
Muestra de entrada
APPAPT
salida de la muestra
Indicación: longitud de la cadena de entrada no supera el 10 5. , Puede ser relativamente grande, como resultado de que sólo da salida a un resultado de tomar un resto 1000000007.

La idea principal de
tiempo de espera de la violencia directa.
Aquí Insertar imagen DescripciónAquí Insertar imagen Descripción

#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;
}

Esta pregunta se hace ideas muy interesantes para resolver problemas, vale la pena un vistazo más de cerca.

algoritmo de selección aleatoria

Se centra en la pregunta: ¿cómo (suponiendo que el número de matriz varía) gran número de K obtenido a partir de la matriz en un desordenado. El principio del algoritmo de selección aleatoria es similar al algoritmo de ordenación rápida al azar , el código es el siguiente:

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);
}

La aplicación de un algoritmo de selección aleatoria:

Para un conjunto dado de números enteros, un conjunto de números enteros varían, se divide en dos subconjuntos ahora quieren, y que tanto la propia como la serie original de conjunto a través del vacío, mientras que en los dos subconjuntos el número de elementos de n2 n1 del valor absoluto de la diferencia | n1-n2 | premisa tan pequeños como sea posible, los requisitos de sus respectivos elementos de la S1 y S2 y la diferencia en valor absoluto de | S1-S2 | lo más grande posible. Busque | S1-S2 |.

De hecho, n / 2 en busca de conjunto de elementos más grandes, mientras que según el número del conjunto en dos partes

#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;
}

problema:

K-buscando gran número

Dada una longitud de n (1≤n≤1,000,000) secuencia desordenada de números enteros positivos, y otro número k (1≤k≤1,000,000) (acerca de los k-th números más grandes: {1,2,3,4 secuencia, por ejemplo, 5, 6} en el tercer número es mayor 4.)
de entrada
de la primera línea de dos números enteros positivos m, n.
La segunda línea de números enteros n positivos.
Salida
k-ésimo número más grande.
entrada de la muestra
. 6. 3
. 1. 3 2 4. 5. 6
Salida de muestra
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;
}
Publicado 43 artículos originales · ganado elogios 4 · Vistas 1209

Supongo que te gusta

Origin blog.csdn.net/weixin_42176221/article/details/101788562
Recomendado
Clasificación