Algorithme pour trouver les Numéros de la Chance

Je suis tombé sur cette question.Un nombre est appelé la chance si la somme de ses chiffres, ainsi que la somme des carrés de ses chiffres est un nombre premier. Combien de nombres compris entre A et B sont de la chance? 1 <= A <= B <= 1018. J'ai essayé ce.

  • J'ai d'abord généré tous les possibles de nombres premiers entre 1 et le nombre qui pourrait être entraîné par l'addition des places (81 *18 = 1458).
  • J'ai lu dans A et B, trouver le nombre maximal pouvant être obtenus en additionnant les chiffres, Si B est un nombre à 2 chiffres ( le nombre maximum est de 18 généré par 99).
  • Pour chaque nombre premier entre 1 un nombre maximum. J'ai appliqué entier partition de l'algorithme.
  • Pour chaque partition, j'ai vérifié si leur somme des carrés de leurs chiffres forment le premier. Si donc les permutations possibles de cette partition sont générés et s'ils se trouvent dans la gamme, ils sont des numéros de la chance.

C'est la mise en œuvre:

#include<stdio.h>
#include<malloc.h>
#include<math.h>
#include <stdlib.h>
#include<string.h>
long long luckynumbers;
int primelist[1500];
int checklucky(long long possible,long long a,long long b){
int prime =0;
while(possible>0){
prime+=pow((possible%10),(float)2);
possible/=10;
}
if(primelist[prime]) return 1;
else return 0;
}
long long getmax(int numdigits){
if(numdigits == 0) return 1; 
long long maxnum =10;
while(numdigits>1){
maxnum = maxnum *10;
numdigits-=1;
}
return maxnum; 
}
void permuteandcheck(char *topermute,int d,long long a,long long b,int digits){
if(d == strlen(topermute)){
long long possible=atoll(topermute);
if(possible >= getmax(strlen(topermute)-1)){  //to skip the case of getting already read numbers like 21 and 021(permuted-210
if(possible >= a && possible <= b){
luckynumbers++;
}
}
}
else{
char lastswap ='\0';
int i;
char temp;
for(i=d;i<strlen(topermute);i++){
if(lastswap == topermute[i])
continue;
else
lastswap = topermute[i];
temp = topermute[d];
topermute[d] = topermute[i];
topermute[i] = temp;
permuteandcheck(topermute,d+1,a,b,digits);
temp = topermute[d];
topermute[d] = topermute[i];
topermute[i] = temp;
}
}
}
void findlucky(long long possible,long long a,long long b,int digits){
int i =0;
if(checklucky(possible,a,b)){
char topermute[18];
sprintf(topermute,"%lld",possible);
permuteandcheck(topermute,0,a,b,digits);
}
}
void  partitiongenerator(int k,int n,int numdigits,long long  possible,long long a,long long b,int digits){
if(k > n || numdigits > digits-1 || k > 9) return;
if(k == n){
possible+=(k*getmax(numdigits));
findlucky(possible,a,b,digits);
return;
}
partitiongenerator(k,n-k,numdigits+1,(possible + k*getmax(numdigits)),a,b,digits);
partitiongenerator(k+1,n,numdigits,possible,a,b,digits);
}
void calcluckynumbers(long long a,long long b){
int i;
int numdigits = 0;
long long temp = b;
while(temp > 0){
numdigits++;
temp/=10;
}
long long maxnum =getmax(numdigits)-1;
int maxprime=0,minprime =0;
temp = maxnum;
while(temp>0){
maxprime+=(temp%10);
temp/=10;
}
int start = 2;
for(;start <= maxprime ;start++){
if(primelist[start]) {
partitiongenerator(0,start,0,0,a,b,numdigits);
}
}   
}   
void generateprime(){
int i = 0;
for(i=0;i<1500;i++)
primelist[i] = 1;
primelist[0] = 0;
primelist[1] = 0;
int candidate = 2;
int topCandidate = 1499;
int thisFactor = 2;
while(thisFactor * thisFactor <= topCandidate){
int  mark = thisFactor + thisFactor;
while(mark <= topCandidate){
*(primelist + mark) = 0;
mark += thisFactor;
}
thisFactor++;
while(thisFactor <= topCandidate && *(primelist+thisFactor) == 0) thisFactor++;
}
}
int main(){
char input[100];
int cases=0,casedone=0;
long long a,b;
generateprime();
fscanf(stdin,"%d",&cases);
while(casedone < cases){
luckynumbers = 0;
fscanf(stdin,"%lld %lld",&a,&b);
int i =0;
calcluckynumbers(a,b);
casedone++;
}
}

L'algorithme est trop lent. Je pense que la réponse peut être trouvée, basée sur la propriété des nombres.Veuillez partager vos pensées. Merci.

  • Bug: primelist est de dimension 1400 mais vous traiter comme si elle est de dimension 1500
  • Je pense que cette question devrait être déplacé vers la codereview.stackexchange.com
  • R, je ne pense pas que c'est une grosse affaire
  • Mais l'algorithme est lente. Il doit être améliorée ou un nouvel devraient être trouvées.
  • vous pensez que l'écriture au-delà de la fin d'un tableau "n'est pas un big deal" ???
  • êtes-vous sûr que ce n'est pas des devoirs?
  • Ce n'est pas de devoirs. Mais c'est à partir du site web InterviewStreet.com. La résolution du problème est une chose. La résolution dans le temps qu'ils allouent est une autre bête complètement.

InformationsquelleAutor vgeta | 2012-01-26