前提・実現したいこと
1p1^np2^n*p3^n (n>=0) (p1,p2,p3は2<=p1,p2,p3<=7を満たす素数)を満たす整数を小さい順に並べk(1<=k<=1000)番目に小さい値をできるだけ計算量を少なく求めたいです。
具体例
p1=2,p2=3,p3=5,k=4のとき)
1番目 1p1^0p2^0p3^0 = 1
2番目 1p1^1p2^0p3^0 = 2
3番目 1p1^0p2^1p3^0 = 3
4番目 1p1^2p2^0p3^0 = 4
5番目 1p1^0p2^0*p3^1 = 5
となり、求める値は4
発生している問題・エラーメッセージ
下記ソースコードで実行したところ900番目あたりから計算量が多くなりすぎて、CPU占有率が100%に張り付いてしまいました。
該当のソースコード
C言語
1#include <stdio.h> 2#include <string.h> 3#include <stdlib.h> 4#include <stdbool.h> 5#include <math.h> 6#pragma warning(disable : 4996) //_CRT_SECURE_NO_WARNINGS 7int main(void) { 8 int p1, p2, p3, k; 9 long long int temp, res = 2; 10 int cnt = 1; 11 long long int data[1000]; 12 data[0] = 1; 13 scanf("%d%d%d%d", &p1, &p2, &p3, &k); 14 while (cnt <= k - 1) { 15 temp = res; 16 while (res % p1 == 0) { 17 res = res / p1; 18 if (res == 1)break; 19 } 20 while (res % p2 == 0) { 21 res = res / p2; 22 if (res == 1)break; 23 } 24 while (res % p3 == 0) { 25 res = res / p3; 26 if (res == 1)break; 27 } 28 if (res == 1) { 29 data[cnt] = temp; 30 cnt++; 31 } 32 res = temp + 1; 33 } 34 if (k ==1) { 35 printf("%d\n", 1); 36 } 37 else { 38 printf("%lld\n",data[k - 1]); 39 } 40 return 0; 41}
試したこと
・上記コードではp1,p2,p3いづれの倍数にも当てはまらない数字をスキップしながら、dataに値を格納しています。
・その他考えたプログラムは3重ループを書いて1*p1^(0-n)*p2^(0-n)*p3^(0-n)のすべての組み合わせを求めた後にqsortして1000番目を求めようとしました。
しかし1000番目を求めるためにはかなり大きな配列を用意しなければいけないので、あまり有効な方法だとは思いません。
補足情報(FW/ツールのバージョンなど)
言語:C言語
OS:Windows8 64bit
回答3件
あなたの回答
tips
プレビュー