• 締切済み

このソースコードについて

AOJにてこのコードを提出したところTime Limit Exceededでドロップされました。 Visual studio 2013 で動かしたところ特に怪しい挙動や間違いを出力することはなかったのですが。。。 ちなみに言語はC++です。 問題のURL http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0056 #include<iostream> #include<math.h> using namespace std; int p[20000],d; void primefinder(int a){ p[0] = 2; int k, l = 0; for (int i = 3; i <= a; i++){ k = (int)sqrt(i); for (int j = 2; j <= k + 1; j++){ if (j == k + 1){ p[++l] = i;} else if (i%j == 0)break; } } d = l + 1; } int main(){ int n,m,q,count; while ((cin >> n), n){ count = 0; m = n / 2; primefinder(m); for (int i = 0; i < d; i++){ q = n - p[i]; if (q <= 1)continue; for (int j = 2; j <= (int)sqrt(q)+1; j++){ if (j == (int)sqrt(q) + 1)count++; else if (q%j == 0)break; } } cout << count << endl; } }

みんなの回答

  • maiko0333
  • ベストアンサー率19% (840/4403)
回答No.2

ロジックの改善をしましょう。 例えば、 for (int j = 2; j <= k + 1; j++){  if (j == k + 1){ p[++l] = i;}  else if (i%j == 0)break;  } } ここに無駄があります。 2重ループですとかなりロスしているのでは? k=9の時、jは2から増えていき、k+1まで3,4,5,6,7,8,9,10までループし、 if (j == k + 1){ p[++l] = i;}というのは最後のk=10の時だけですよね。 では、外に出しましょう。 例えば、 for (int j = 2; j <= k + 1; j++){ if (i%j == 0)break; } if(j==k) p[++l] = i; のほうが速いはずですね。

  • f272
  • ベストアンサー率46% (7998/17099)
回答No.1

原因ははっきりしていて「Time Limit Exceeded」ですね。ようするに時間がかかりすぎているということです。

関連するQ&A

  • C++のソースコードについて

    このコードを書いてビルドまでノーエラーで通ったのですがいざ起動してみると起動した瞬間に動作を停止しました。と表示されて何もできません。 #include<iostream> #include<algorithm> using namespace std; int main(){ long long d[2000], e[2000]; int w[2000], h[2000], a[1501 * 1024], b[1502 * 1024], n, m; while (cin >> n >> m, n){ long k = 1, l = 1, count = 0, f = 0; for (int i = 0; i < n; i++) { d[i] = 0; cin >> w[i]; if (!i)d[0] = w[i]; else d[i] += w[i] + d[i - 1]; } for (int i = 0; i < m; i++) { e[i] = 0; cin >> h[i]; if (!i)e[0] = h[i]; else e[i] += h[i] + e[i - 1]; } a[0] = d[0]; b[0] = e[0]; for (int i = 1; i < n; i++) for (int j = 0; j < i; j++){ a[k] = d[i] - d[j]; k++; } for (int i = 1; i < m; i++) for (int j = 0; j < i; j++){ b[l] = e[i] - e[j]; l++; } sort(a, a + n); sort(b, b + m); for (int i = 0; i < n; i++){ for (; f < m; f++){ if (a[i] == b[f]){ count++; f++; break; } if (a[i] < b[f])break; } } cout << count << endl; } } ちなみにこの問題はhttp://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2015 です

  • Cのソースコードについて

    #include<stdio.h> int main(void) { long a[6000],sum[6000],max=0; int i,j=0,n,m; for (m = 0; m <= 6000; m++) sum[m] = 0; for (i = 0;; i++) { scanf_s("%ld", &a[i]); if (a[i] > 0) sum[j] += a[i]; else if (a[i] < 0) { j++; sum[j] = -1; j++; } else break; } for (n = 0; sum[n] == 0; n++) { if (max < sum[n]) max = sum[n]; } printf("%ld",max); while(1){} return 0; } こんなコードを書いたのですが 答えが常に0になってしまいます。 原因がはっきりしないので教えてください 使用言語はCです

  • 3次元配列のループによる比較の回数を減らす

    以下は正の整数が入った3次元配列form[30][20][8]で、中身が一致している2カ所に-1を代入してループを抜けるというプログラムの一部分なんですが、無駄なループを減らすにはどういった変更をすればいいでしょうか? form[30][20][8]は変更しない方向でお願いします。 check: for(int i=0;i<30;i++){ for(int j=0;j<20;j++){ for(int k=0;k<8;k++){ for(int l=0;l<30;l++){ for(int m=0;m<20;m++){ for(int n=0;n<8;n++){ if(form[i][j][k]==form[l][m][n]&&!(i==l&&j==m&&k==n)form[i][j][k]!=-1) count++; form[i][j][k]=-1; form[l][m][n]=-1; break check; } } } } } } }

    • ベストアンサー
    • Java
  • 4つの数字を用いて重複することなく並べる

    題名のとおりなのですが 例えば{1,2,3,4},{2,3,4,1}などです。 これら24通りを[24][4]の要素をもつ2次元配列に入れたいのですがどうすればいいのでしょうか? 一応自分で作ってみたのですが作ってみていかにも冗長であると感じています。 アドバイス、回答よろしくお願いします。 #include <stdio.h> int main(void){ int i,j,n=5,m,p; int l[24][4]={{1,2,3,4},{2,1,3,4},{2,3,1,4},{3,2,1,4},{3,2,4,1},{4,2,3,1}}; for(i=0;i<6;i++){ for(j=0;j<3;j++){ n++; if(!j)for(p=0;p<4;p++)l[n][p]=l[i][p];     else for(p=0;p<4;p++)l[n][p]=l[n-1][p]; m=l[n][0]; l[n][0]=l[n][1]; l[n][1]=l[n][2]; l[n][2]=l[n][3]; l[n][3]=m; } } for(i=0;i<24;i++){ for(j=0;j<4;j++){ printf("%d",l[i][j]); } printf("\n"); } return 0; }

  • C+のsqrt

    icpcの過去問(http://www.deqnotes.net/acmicpc/3006/ja)で、答えを #include <cmath> #include <iostream> using namespace std; #define max 1000000 int main(){ //int max = 100; int a,d,n,number[1000010]; for(int i=0;i<max;i++){ number[i] = 1; } number[0]=0;number[1]=0; for(int i=2;i<=sqrt(max)+1;i++){ if(number[i]){ for(int j=i*2;j<max;j=j+i){ number[j] = 0; } } } while(cin >> a >> d >>n,a||d||n){ int count =0; for(int i=a;i<=max;i=i+d){ if(number[i]){count ++; if(count == n){cout << i << endl;break;} } } } } と書いたところ、PKUで Main.cpp F:\temp\11386803.6056\Main.cpp(15) : error C2668: 'sqrt' : ambiguous call to overloaded function math.h(581): could be 'long double sqrt(long double)' math.h(533): or 'float sqrt(float)' math.h(128): or 'double sqrt(double)' while trying to match the argument list '(int)' F:\temp\11386803.6056\Main.cpp(16) : error C2108: subscript is not of integral type というコンパイルエラーがでます。 sqrtの前後で型が違っているのは分かるのですが、具体的にどうなおせばよいかわかりません。

  • Javaで数独の自動解法プログラム

    Javaで次のようなプログラムを作りました。 次に、ここから実行で得られた数独を自動解法プログラムによって、解が「1つ or 複数」かを調べるようにしたいのですが、その自動解法プログラムは新しく作らなければいけないのでしょうか。 import java.util.Random; public class NumberPlace { public static void main(String[] args) { int i, j, k, l, m, n, check=0, count=0, tmp; int a[][] = new int [9][9]; Random rnd = new Random(); int ran; Random rnd1 = new Random(); int ran1; Random rnd2 = new Random(); int ran2; boolean A=false; while(A==false){ A=true; for ( i=0; i<9; i++ ) for ( j=0; j<9; j++ ) a[i][j] = 0; count = 0; for ( i=0; i<9; i++ ) { for ( j=0; j<9; j++ ) { ran = rnd.nextInt(9); tmp = ran + 1; check = 0; //System.out.println(tmp); for ( k=0; k<j; k++ )  //横列に入る数字をチェック if ( a[i][k] == tmp ) check = 1; for ( k=0; k<i; k++ )  //縦列に入る数字をチェック if ( a[k][j] == tmp ) check = 1; for ( k=(i/3)*3; k<(i/3)*3+3; k++ )  //ボックスに入る数字をチェック for ( l=(j/3)*3; l<(j/3)*3+3; l++ ) if ( a[k][l] == tmp ) check = 1; if ( check == 0 ) a[i][j] = tmp; if ( check == 1 ) j--; if ( count > 50000 ){ A=false;break;} count++; } count = 0; } } for ( i=0; i<30; i++ ) {    //0を入れる回数 ran1 = rnd1.nextInt(9); m = ran1; ran2 = rnd2.nextInt(9); n = ran2; if ( a[m][n] == 0 ) {  //0にしようとした場所が既に0だったら直前に戻る i--; } a[m][n] = 0; } for ( i=0; i<9; i++) { for ( j=0; j<9; j++ ) { if ( a[i][j] < 10 ) { System.out.print(" "); } System.out.print(a[i][j]);       } System.out.print("\n"); } } } これを(最初に入れる0の数を30個として)実行すると、次のようになります。 0 7 6 9 4 1 8 2 5 2 0 5 3 7 0 9 4 0 9 0 4 8 2 5 0 3 7 1 0 2 0 0 0 5 0 6 6 9 3 1 0 0 0 8 2 7 0 8 0 0 0 0 1 4 0 0 0 0 0 0 0 0 3 4 3 0 5 6 8 2 7 9 5 2 9 4 3 7 0 0 8 皆さんの回答の程宜しくお願いします。

  • 線形補間法プログラム(C++)

    C++言語で線形補間法のプログラムを組んで実行しているのですが、どしてもうまくいきません。ただ2倍の画像を作っているだけなのですが・・・。 以下プログラムを載せます、おおよその場所はわかるのですがどうすれば通るのかわかりません。どう直したらよいのか分かる方がいましたらご教授お願いします。 ※bmp[0]:現画像 pic:bmp[0]の縦横2倍の画像 // 線形補間法 // int zx = 2; int zy = 2; int i,j,m,n; float x,y,p,q; int xs = bmp[0]->Width/2; int ys = bmp[0]->Height/2; int d; for(i = -ys; i < ys; i++){ for(j = -xs; j < xs; j++){ y = i/zy; x = j/zx; if(y > 0){ m = (int)y; }else{ m = (int)(y-1);} if(x > 0){ n = (int)x; }else{ n = (int)(x-1);} q = y - m; p = x - n; if(q == 1){q = 0; m = m + 1;} if(p == 1){p = 0; n = n + 1;} if((m >= -ys)&&(m < ys)&&(n >= -xs)&&(n < xs)){ d = (int)((1.0 - q) * (1.0 - p) * (bmp[0]->GetPixel( m + ys, n + xs)) //おそらくこの辺に問題があるかと思われます。 + p * (bmp[0]->GetPixel( m +ys, n + xs)) + q * (1.0 - p) * (bmp[0]->GetPixel(m + 1 + ys, n + xs)) + p * (bmp[0]->GetPixel(m + 1 + ys, n + 1 + xs))); }else{ d = 0; } if(d < 0){d = 0;} if(d > 255){d = 255;} pic->SetPixel(i + ys, j + xs) = d; } } pictureBox2->Image = pic; }

  • c言語

    c言語で写真の課題を出されたのですが自分のプログラムでは上手くいきません。どこが間違っているのか教えて欲しいです。 自分のプログラム #include<stdio.h> #include<math.h> int main(){ int i,j; double c,d,x,y,z; for(i=0;i<=360;i++){ c=10*cos(i*M_PI/180); d=10*sin(i*M_PI/180); if(c>=0 && d>=0){ for(j=0;j<=1000;j++){ x=0.001*j; y =x*d/c; z=1-x*x-(sqrt(x)+y)*(sqrt(x)+y); if(z<=0.0){break;} } } if(c<=0 && d>=0){ for(j=0;j<=1000;j++){ x=-0.001*j; y=x*d/c; z=1-x*x-(sqrt(-x)+y)*(sqrt(-x)+y); if(z<=0.0){break;} } } if(c<=0 && d<=0){ for(j=0;j<=1000;j++){ x=-0.001*j; y=x*d/c; z=1-x*x-(sqrt(-x)+y)*(sqrt(-x)+y); if(z<=0.0){break;} } } if(c>=0 && d<=0){ for(j=0;j<=1000;j++){ x=0.001*j; y=x*d/c; z=1-x*x-(sqrt(x)+y)*(sqrt(x)+y); if(z<=0.0){break;} } } printf("x=%lf y=%lf z=%lf\n",x,y,z); } return(0); }

  • 数独のJavaプログラム

    数独の解答を一発で出すプログラムを考えています。 自分が考えたプログラムは下記の通りです。 import java.util.Random; public class NumberPlace { public static void main(String[] args) { int i, j, k, l, check=0, count=0, tmp; int a[][] = new int [9][9]; Random rnd = new Random(); int ran; for ( i=0; i<9; i++ ) for ( j=0; j<9; j++) a[i][j] = 0; count = 0; for ( i=0; i<9; i++ ) { for ( j=0; j<9; j++) { ran = rnd.nextInt(9); tmp = ran + 1; check = 0; for ( k=0; k<j; k++ ) if ( a[i][k] == tmp ) check = 1; for ( k=0; k<i; k++ ) if ( a[k][j] == tmp ) check = 1; for ( k=(i/3)*3; k<(i/3)*3+3; k++ ) for ( l=(j/3)*3; l<(j/3)*3+3; l++ ) if ( a[k][l] == tmp ) check = 1; if ( check == 0 ) a[i][j] = tmp; if ( check == 1 ) j--; if ( count > 50000 ) break; count++; } count = 0; } for ( i=0; i<9; i++) { for ( j=0; j<9; j++ ) { if ( a[i][j] < 10 ) { System.out.print(" "); } System.out.print(a[i][j]); } System.out.print("\n"); } } } これを実行すると、正しい数独の解が出来るまでに実行を20~30回。多い時は200回前後実行しないと出来ません。 実行結果(0は数独のルール上数字が入らない所) 9 3 6 5 4 1 7 8 2 1 7 4 2 9 6 5 3 0 5 2 8 7 3 0 0 0 0 2 1 5 3 7 8 4 6 9 8 6 3 4 1 9 2 7 5 4 9 7 6 5 2 1 0 0 7 5 1 8 6 4 9 2 3 3 8 2 9 0 0 0 0 0 6 4 9 1 2 5 8 0 0 これを一発で0がない状態にしたいのです。 因みにC言語だと下記のプログラムで一発で出るのですが。(前回質問したプログラム) int main(void) { int i,j,k,l,chk=0,num=0,tmp,count=0; int a[9][9];  srand((unsigned) time(NULL)); start: count=0; for(i = 0; i < 9; i++) for(j = 0; j < 9; j++) a[i][j]=0; for(tmp=1;tmp<10;tmp++){ num=0; while(num<9){ i = rand() % 9; j = rand() % 9; chk=0; for(k=0;k<9;k++) if(a[i][k]==tmp)chk=1; for(k=0;k<9;k++) if(a[k][j]==tmp)chk=1; for(k=(i/3)*3;k<(i/3)*3+3;k++){ for(l=(j/3)*3;l<(j/3)*3+3;l++){ if(a[k][l]==tmp)chk=1; } } if((chk==0)&&(a[i][j]==0)){ a[i][j]=tmp; num++; } if(count%100==99){ count++; for(i = 0; i < 9; i++) for(j = 0; j < 9; j++) if(a[i][j]==tmp)a[i][j]=0; num=0; } if(count>10000) goto start; count++; } } for(i = 0; i < 9; i++){ for(j = 0; j < 9; j++){ printf("%d ",a[i][j]); } printf("\n"); } return 0; } このプログラムを実行すると一発で解答が出ます。 上のJavaプログラムを下のプログラムのようにするにはどうしたら良いでしょうか。

    • ベストアンサー
    • Java
  • プログラムを組んだのにエラーが出る!!!

    #include <stdio.h> #include <stdlib.h> #include <math.h> int main(void) { int i, j; int m, flag, count; FILE *fp; if (NULL == (fp = fopen("prime.txt", "w"))) { printf("Cannot open output file\n"); exit(1); } count = 0; for (i = 2; i < 1000; i++) { m =sqrt(i); flag = 1; for (j = 2; j <= m; j++) { if (i % j == 0) { flag = 0; break; } count++; } if (flag) { printf("%4d ", i); fprintf(fp," %4d", i); } } printf("\n乗除回数:%d\n", count); fprintf(fp,"\n乗除回数 %d\n", count); fclose(fp); return 0; } (通常課題2-3 1000以下の正の整数値のうち,素数をすべて計算し,結果をファイルに格納するプログラムを作れ. .また、計算の実行の中で乗除を行った回数もあわせて表示し、ファイルに格納すること 実行結果 2 3 5 7 11 13 17 … 991 997 乗除回数:78022 どこが間違ってるのか指摘してください お願いします!

専門家に質問してみよう