(Violence + Optimisation de la table de hachage) Blue Bridge Cup 2016C\C++A Compétition provinciale Zhenti 8Square Sum

sujet

Le théorème des quatre sommes des carrés, également connu sous le nom de théorème de Lagrange :
  chaque entier positif peut être exprimé comme la somme des carrés d'au plus quatre entiers positifs.
  Si vous incluez 0, il peut être exprimé comme la somme des carrés de 4 nombres.

Par exemple :
  5 = 0^2 + 0^2 + 1^2 + 2^2
  7 = 1^2 + 1^2 + 1^2 + 2^2
  (le symbole ^ signifie puissance)

Pour un entier positif donné, il peut y avoir plusieurs représentations de la somme des carrés.
  Vous devez trier 4 nombres :
  0 <= a <= b <= c <= d
  et trier toutes les représentations possibles dans l'ordre croissant par a,b,c,d comme clé primaire commune, et enfin sortir la première représentation

L'entrée du programme est un entier positif N (N<5000000), et il est
  nécessaire de sortir 4 entiers non négatifs, triés de petit à grand, séparés par des espaces

Par exemple, entrez :
  5 ,
  puis le programme doit afficher :
  0 0 1 2

Pour un autre exemple, entrez :
  12
  , le programme devrait afficher :
  0 2 2 2

Pour un autre exemple, entrez :
  773535
  , le programme devrait afficher :
  1 1 267 838

Convention de ressource :
  pic de consommation mémoire < 256M
  consommation CPU < 3000ms

analyser

Lorsque vous rencontrez un problème d'algorithme, s'il n'y a pas de meilleure méthode, pensez d'abord à une méthode violente, et la méthode violente peut également obtenir une partie des points, puis en cas de répétition, la méthode violente d'optimisation de
ce problème est pour énumérer a La plage de ,b,c,d est le nombre racine n, et la complexité temporelle est d'environ O(n^2).La plage de n donnée dans la question est 1e6, donc le pire des cas est d'environ 1e12
. 1. Réduire la
plage d'énumération
2. Réduire les variables d'énumération
1 n'est pas faisable, nous pouvons donc envisager de réduire les variables d'énumération La
première chose à laquelle on peut penser est d'omettre l'énumération de d, vous pouvez utiliser Na ab bc c pour représenter d, Le pire des cas sera probablement réduit à 1e9, et il expirera également.
Ensuite, omettez c et d, et stockez na
ab b pour représenter c c + d d, mais pour le moment nous ne savons pas ce que c et d sont, donc cette valeur doit être Pour lier avec la valeur de c ou d, nous avons pensé à une table de hachage, en utilisant la table de hachage pour lier c c + b b et c, si nécessaire, soustrayez directement cette valeur de c c et puis placez-le au carré pour obtenir
À ce moment, nous n'avons qu'à énumérer les deux derniers éléments, puis à stocker toutes les combinaisons dans la carte, puis à énumérer a et b, à trouver na ab b dans la carte s'il est trouvé, à affecter c directement, et puis calculez d , la réponse est trouvée, la boucle ici doit suivre l'ordre lexicographique, et la première trouvée qui correspond à la réponse est la réponse

code ca complet

#include <bits/stdc++.h>
using namespace std;

map<int,int>cache;

int main (void)
{
    
    
	int n;
	cin>>n;
	
	for(int c=0;c*c<=n/2;c++)		//存储后两个数字的平方和 
		for(int d=c;d*d+c*c<=n;d++)
		{
    
    
			if(cache.find(c*c+d*d)==cache.end())
				cache[c*c+d*d]=c;
		} 
		
	for(int a=0;a*a<=n/4;a++)		//循环遍历前两个数字 
		for(int b=a;a*a+b*b<=n/2;b++)
		{
    
    
			if(cache.find(n-a*a-b*b)!=cache.end())
			{
    
    
				int c=cache[n-a*a-b*b];
				int d=sqrt(n-a*a-b*b-c*c);
				printf("%d %d %d %d",a,b,c,d);
				return 0;
			}
		}
		
	return 0;	
}

Résumer

La complexité temporelle de la boucle est d'environ O(n) La complexité temporelle de la recherche dans la carte est d'environ O(logn), donc les données d'évaluation ici peuvent passer.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_46035615/article/details/123925307
conseillé
Classement