• 締切済み

奇数魔方陣

下記のプログラム(奇数魔方陣) について最初のfor文からどのような処理が行われているかわかりません。 { int mahoujin[10][10],x,y,i,n = 7; x = n / 2 + 1; y = 1; mahoujin[x][y] = 1; for( i = 2; i <= n * n; i++ ){ if( i % n == 1 ){ y = y + 1; }else{ x = x + 1; y = y - 1; } if( x > n ) x = 1; if( y < 1 ) y = n; mahoujin[x][y] = i; } for( y = 1; y <= n; y++ ){ for( x = 1; x <= n; x++ ){ printf( "%3d ", mahoujin[x][y] ); } printf( "\n" ); } 特にわからないのがif文で分岐になるところどのようなことが行われているかがわからないです。どなたか教えて頂けるとうれしいです。

みんなの回答

  • paspas
  • ベストアンサー率52% (47/90)
回答No.4

if( x > n ) x = 1; if( y < 1 ) y = n; について補足いたします。 xは横軸のカウンタで順番に1ずつあがっていきます。 配列は、7までしかありませんから7列目をを越えると1列目に戻るようになっています。 また、yは縦軸のカウンタで1ずつ減っていきます。 1より小さくなったときn(この場合7)行目にセットするようになっています。 おわかりでしょうか?

  • paspas
  • ベストアンサー率52% (47/90)
回答No.3

再度補足です。 実行するとこのような結果が得られます。 30 39 48 1 10 19 28 38 47 7 9 18 27 29 46 6 8 17 26 35 37 5 14 16 25 34 36 45 13 15 24 33 42 44 4 21 23 32 41 43 3 12 22 31 40 49 2 11 20 x = x + 1; y = y - 1; は数字が右斜め上にあがっていく様子を表します。 if( x > n ) x = 1; if( y < 1 ) y = n; は配列からあふれたときの処理です。

hiki_zero
質問者

補足

x = x + 1; y = y - 1; は数字が右斜め上にあがっていく様子を表します。 if( x > n ) x = 1; if( y < 1 ) y = n; は配列からあふれたときの処理です。 >この部分の処理内容がまだ理解できません とくにif文のところはこのプログラムで一つ例を挙げて説明していただけませんでしょうか? ちなみにnは7ということはわかりますが、 7よりx が大きい時が1?1よりyが小さいときが7? がいまいち理解できません。

  • paspas
  • ベストアンサー率52% (47/90)
回答No.2

補足です。 i % n == 1 というのは、 i を 7で割ったあまりが1の場合です。 今回の場合、n=7ですので、1あまるのは、8,15,22,29,36,43となります。 このときに、y=y+1 つまり、前の値の下の段に移動します。

hiki_zero
質問者

お礼

この部分はわかりました。 ありがとうございます。

  • paspas
  • ベストアンサー率52% (47/90)
回答No.1

魔法陣の数字の並び方に規則性があります。 その規則をプログラム上で実現しているだけです。 あなたがかかれているプログラムを実行し、1から順に数字を見ていけば規則性がわかります。  最初のif文は段の変化するところ、残りのif文は魔法陣の配列からはみ出したときの処理ですね。

hiki_zero
質問者

補足

for( i = 2; i <= n * n; i++ ){ if( i % n == 1 ){ >ここで1から順に入るのはわかります。が、ここでどのような場合が y = y + 1; になるのかがわかりません。 }else{ x = x + 1; y = y - 1; } if( x > n ) x = 1; if( y < 1 ) y = n; mahoujin[x][y] = i; } >また上記までの流れを数値が格納されるにつれどうなっていくというのがわかりません。

関連するQ&A

  • n次の奇数魔方陣をつくるプログラム

    どうしてもエラーが出てしまいます。少なくとも、「int mahojin[n+1][n+1],i,j,k;」あたりの行が間違っているらしいのですが、なぜだかわかりません。アドバイスお願いします!!(スペースが上手く入らなくて、全角スペースを使ってますが気にしないでください。) #include<stdio.h> int main(void) {  int n;  printf("n(ただし、nは奇数)=?");scanf("%d",&n);  int mahojin[n+1][n+1],i,j,k;  j=(n+2)/2;i=0;  for(k=1;k<=n*n;k++){     if((k%n)==1)      i++;     else {      i--;j++;     }     if(i==0)      i=n;     if(j>n)      j=1;     mahojin[i][j]=k;   }   printf(" %d次の魔方陣 \n",n);   for(i=1;i<=n;i++){     for(j=1;j<=n;j++)      printf("%4d",mahojin[i][j]);     printf("\n");   }   return 0; }

  • n(nは奇数)次の魔方陣

    奇数nに対してn次の魔方陣を作るプログラムを、誰か教えてください。

  • ラテン方陣と魔方陣

    魔方陣について、縦と横の和が同じで(斜めは考えない)、すべての数が一回ずつしか現れないものとします。ラテン方陣という縦の各列も横の各列も同じ数字が一回しか現れないものと定義づけます。このラテン方陣は作り方により2種類にわかれ、この2種のラテン方陣を組み合わせた方陣をオイラー方陣と名づけます。たとえば、3×3のラテン方陣は 123   123         312 と 231         231   312 となり、これを組み合わせた3次のオイラー方陣は       (1,1)(2,2)(3,3)       (3,2)(1,3)(2,1)       (2,3)(3,1)(1,2) となります。 これらの定義条件下において次の定理を証明してほしいのですが。 定理. n×nの二つのラテン方陣からできるオイラー方陣にお いて、nが奇数ならば、(1,1)、(1,2)、・・・(n,n)のすべての組が方陣内にちょうど一回ずつ現れる。 どうかよろしくお願いしますm(__)m       

  • C言語の問題がわからないです。

    C言語のプログラムで、列数を自分で決めて、 (例)3列         ●(この行を最後として)   □● ●□● 上記のプログラムを作りたいのですが、 上手くいきません。途中まで作ったのですが、なかなか思うようにいかないです。どうすれば上記のようになりますでしょうか? #include <stdio.h> void disp(int x, int y); main() { int i,n; printf("表示する列:"); scanf("%d",&n); disp(3,3); for(i=1;i<=n;i++){ if(i%2==0){ disp(n-i,4); disp(i,2); } else{ disp(n-i,4); disp(i,1); } disp(1,3); } } void disp(int x, int y) { int i; for(i=0;i<x;i++){ if(y==1){ printf("●"); } else if(y==2){ printf("□"); } else if(y==3){ printf("\n"); } else{ printf("\0"); } } }

  • 初心者です。 配列のエラーがどうしても解決できません。 誰か助けてください・・・

    魔方陣のプログラムを考えて書いてみましたが、 エラーが出てしまい実行することができません。 class mahoujin{ public static void main(String args[]){ int n=3; int a[][] = new int[3][3]; int x=0; int y=1; for(int p=0;p<=3;p++){ for(int q=0;q<=3;q++){ a[p][q]=0;} } for(int i=1;i<=n*n;i++){ if((i%n)==1){x++; }else{x--; y++;} if(x==0){x=3;} if(y==3){y=0;} a[x][y]=i;} } } 空の配列や配列を外れるものがあるかをよく考えてみましたが、どうしても解決できません。助けてください・・・

  • 一番大きい奇数を表示する

    scanf関数を使って数字を10回入力して一番大きなものを表示させるプログラムをつくったのですが、 さらに一番大きな奇数を表示するにはどうすればいいのでしょうか? 偶数=割り切れる 奇数=割り切れない というところまでは分かるのですが、以下のプログラムに奇数を判別するソースを追加するのにはどうすればいいのでしょうか。 #include <stdio.h> int main(void) { char str[1024]; char buf[10]; int i; int w; printf("文字列を10回入力して下さい:\n"); memset(str, 0, sizeof(str)); for (i = 0; i < 10; i++) { memset(buf, 0, sizeof(buf)); printf("input>\n"); scanf("%s", buf); } for (i = 0; i < 10; i++) { if ((buf[i] & 1) == 1) /* 奇数であるか */ { if (strcmp(buf, str) > 0) { strcpy(str, buf); } } } printf("output>\n%s\n" , str); getchar(); }

  • 万年カレンダー

    万年カレンダーの日にちが、一日ずれて表示されますのでその原因を教えてください。 void main() { int nen,tuki,niti; int ff,i,n; int carender[6][7]; niti=0; for(i=0;i<6;i++)for(n=0;n<7;n++) carender[i][n]=0; printf("西暦(4桁)→"); scanf("%d",&nen); printf("month:"); scanf("%d",&tuki); ff=youbi_chk(nen,tuki,1); for(i=ff;i<7;i++) {carender[0][i]=niti;++niti;} for(n=1;n<6;n++){ for(i=0;i<7;i++){ if(niti<=niti_chk(tuki,nen)) {carender[n][i]=niti;++niti;}} } printf(" SUN MON TUE WED THU FRI SAT\n"); for(n=0;n<6;n++){ for(i=0;i<7;i++) if(carender[n][i]==0)printf(" ");else printf("%4d",carender[n][i]); printf("\n");} } int youbi_chk(int y,int m,int d) { int youbi; if(m<3) {y--; m+=10;} else {m-=2;} youbi=(y+(y/4)-(y/100)+(y/400)+(13*m-1)/5+d)%7; return youbi; } int uru_chk(int y) { if(y%400==0) return 1; if(y%100==0) return 0; if(y%4==0) return 1; return 0; } int niti_chk(int m,int y) { int hi[12]={31,28,31,30,31,30,31,31,30,31,30,31}; hi[1]+=uru_chk(y); return hi[m-1]; } プロトタイプ宣言は、省いてます。

  • if文の中にfor文なのか、for文の中にif文なのか

    for文の中に分岐を作って計算するのと、if文を先に書いてからfor文にするのとではどちらが一般的ですか? for ( i = 0; i < n; i++) { if ( a > b ) { y = i; } else { y = i * 2; } printf( "%d", y ); } とするか、 if ( a > b ) { for ( i = 0; i < n; i++) { y = i; } } else { for ( i = 0; i < n; i++) { y = i * 2; } } printf( "%d", y ); とするかという事です。 ちなみにプログラムは適当ですのでちょっとしたミスはご勘弁ください。 個人的には後者の方が分岐が少ない分負担は減ると思うのですが、前者の方がすっきりとしているのでこちらを使いたいのです。 もちろん、微々たる差なので好きな方を使えという意見もあると思いますが、皆さんはどちらを使いますか?

  • N王妃システムの解のタイム計算

    先輩方にご協力をお願いしたく書き込みさせていただきます。 #include <stdio.h> #define FREE 0 #define BUSY 1 #define N 8 int q_pos[N+1]; int colum[N+1]; int r_up[2*N]; int r_dw[2*N]; void disp(void) { int y,x; static count = 0; printf("\n解 %d\n", ++count); for(y=1;y<=N; y++){ for(x=1;x<=N; x++){ if (q_pos[y] == x)printf("○"); else printf("×"); } printf("\n"); } } void eight_queens(int y) { int x; for (x=1; x<=N; x++){ if(colum[x]==FREE && r_up[y+x-1]==FREE && r_dw[y-x+N]==FREE){ q_pos[y]=x; if (y>=N) disp(); else{ colum[x]=BUSY; r_up[y+x-1]= r_dw[y-x+N]=BUSY; eight_queens(y+1); colum[x]=FREE; r_up[y+x-1]= r_dw[y-x+N]=FREE; } } } } int main(void) { int i; for(i=1;i<=N; i++) colum[i]=FREE; for(i=1;i<2*N;i++) r_up[i]= r_dw[i]=FREE; eight_queens(1); return 0; } こちらのプログラムに #include<stdio.h> #include<stdlib.h> #include<time.h> void sleep(clock_t wait); void main(void) { int i,j,n; time_t start,finish; double duration,v; printf("繰り返し回数は>"); scanf("%d",&n); time(&start); v=1.01; for(i=0; i<n; i++) { if(((i+1)% 10)==0) { fprintf(stdout,"."); fflush(stdout); } for(j=0; j<n; j++) { v *=1.0001; } } printf("\n"); time(&finish); duration=difftime(finish,start); printf("計算にかかった時間は約%6.2f 秒です \n", duration); } のプログラムを合体させ、1つのプログラムを完成させたいのですが、どのような配列にしたらいいのか教えて欲しいです>< アルゴリズムとしては、チェスのN王妃のプログラムから解を導きだすと同時に、そのプログラムを起動してから終わりまでのタイムを計算するプログラムを挿入すると言う内容です。 長くてすいません;;

  • 配列を使って魔方陣

    C言語を使って最近やっと配列ができるようになってきたんですが、どうしても魔方陣のやり方がわからないんです。教えてください。 魔方陣とは、1~n^2までの整数をn×nの正方形に並べ、どの行、どの列、どの対角線のn個の数の和も一定の値になるようにしたものです。 nは常に奇数を入力し、1番上の行の中央の列に1を置く事になります。 整数kまで置かれているとすると、k+1は次のように置かれる。 * kの置かれた場所の右斜め上(以下この場所をαと呼ぶ)が空いていれば、そこにk+1を置く。 * αがすでに他の数が置かれているとき、kの置かれている場所のすぐ下にk+1を置く。 * αが右上隅にはみ出す場合は、kの置かれている場所のすぐ下にk+1を置く。 * αが1番上の行からはみ出す場合は、場所αの1番下の列にk+1を置く。 * αが1番右上の列からはみ出す場合には、場所αの1番左の列にk+1を置く。 例)n=3のとき 8 1 6 3 5 7 4 9 2 まだまだ初心者なので詳しく教えていただけると嬉しいです。よろしくお願いします。

専門家に質問してみよう