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.