下記のプログラム(奇数魔方陣)
について最初の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文で分岐になるところどのようなことが行われているかがわからないです。どなたか教えて頂けるとうれしいです。

A 回答 (4件)

if( x > n ) x = 1;


if( y < 1 ) y = n;

について補足いたします。

xは横軸のカウンタで順番に1ずつあがっていきます。
配列は、7までしかありませんから7列目をを越えると1列目に戻るようになっています。

また、yは縦軸のカウンタで1ずつ減っていきます。
1より小さくなったときn(この場合7)行目にセットするようになっています。

おわかりでしょうか?
    • good
    • 0

再度補足です。



実行するとこのような結果が得られます。

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;

は配列からあふれたときの処理です。

この回答への補足

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?
がいまいち理解できません。

補足日時:2003/10/29 21:35
    • good
    • 0

補足です。



i % n == 1

というのは、 i を 7で割ったあまりが1の場合です。

今回の場合、n=7ですので、1あまるのは、8,15,22,29,36,43となります。
このときに、y=y+1 つまり、前の値の下の段に移動します。
    • good
    • 0
この回答へのお礼

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

お礼日時:2003/10/29 21:34

魔法陣の数字の並び方に規則性があります。


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

この回答への補足

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;
}
>また上記までの流れを数値が格納されるにつれどうなっていくというのがわかりません。

補足日時:2003/10/29 19:05
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q配列を使って魔方陣

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

まだまだ初心者なので詳しく教えていただけると嬉しいです。よろしくお願いします。

C言語を使って最近やっと配列ができるようになってきたんですが、どうしても魔方陣のやり方がわからないんです。教えてください。

魔方陣とは、1~n^2までの整数をn×nの正方形に並べ、どの行、どの列、どの対角線のn個の数の和も一定の値になるようにしたものです。
nは常に奇数を入力し、1番上の行の中央の列に1を置く事になります。
整数kまで置かれているとすると、k+1は次のように置かれる。
* kの置かれた場所の右斜め上(以下この場所をαと呼ぶ)が空いていれば、そこにk+1を置...続きを読む

Aベストアンサー

次のコードでできると思います。n=19までは大丈夫そうでした。インデントに全角スペースを使っているので適当に置換してください。

-------------------------------------------------
#include<stdio.h>
#define SIZE 5 /*奇数を指定*/
int mahoujin[SIZE][SIZE];
int sum_yoko[SIZE], sum_tate[SIZE], sum_naname[2];

int main()
{
  int i, j;
  int row, col;

  /*初期化*/
  row = 0;
  col = SIZE / 2;
  mahoujin[row][col] = 1;

  /*配列への書き込み*/
  for (i = 2; i <= (SIZE * SIZE); i++) {
    if (row == 0 && col >= (SIZE -1))
      row++;
    else if (row == 0)
      row = (SIZE - 1), col++;
    else if (col >= (SIZE -1))
      row--, col = 0;
    else if (mahoujin[row - 1][col + 1] == 0)
      row--, col++;
    else
      row++;

    mahoujin[row][col] = i;
  }

  /*検証*/
  for (i = 0; i < SIZE; i++) {
    for (j = 0; j < SIZE; j++) {
      sum_yoko[i] += mahoujin[i][j]; /*横方向の合計を各行について計算*/
      sum_tate[i] += mahoujin[j][i]; /*縦方向の合計を各列について計算*/
    }
    sum_naname[0] += mahoujin[i][i]; /*左上から右下への合計*/
    sum_naname[1] += mahoujin[i][SIZE - 1 - i]; /*右上から左下への合計*/
  }
  for (i = 0; i < SIZE; i++) {
    if (sum_yoko[i] != sum_naname[0] || sum_tate[i] != sum_naname[0]) {
      printf("魔方陣の生成に失敗しました\n");
      return 0;
    }
  }
  if (sum_naname[0] != sum_naname[1]) {
    printf("魔方陣の生成に失敗しました\n");
    return 0;
  }

  /*画面出力*/
  printf("サイズ%dの魔方陣\n", SIZE);
  for (i = 0; i < SIZE; i++) {
    for (j = 0; j < SIZE; j++)
      printf("%4d", mahoujin[i][j]);
    printf("\n");
  }

  return 0;
}

次のコードでできると思います。n=19までは大丈夫そうでした。インデントに全角スペースを使っているので適当に置換してください。

-------------------------------------------------
#include<stdio.h>
#define SIZE 5 /*奇数を指定*/
int mahoujin[SIZE][SIZE];
int sum_yoko[SIZE], sum_tate[SIZE], sum_naname[2];

int main()
{
  int i, j;
  int row, col;

  /*初期化*/
  row = 0;
  col = SIZE / 2;
  mahoujin[row][col] = 1;

  /*配列への書き込み*/
  for (i...続きを読む

QC言語の課題丸投げ

C言語の課題丸投げ

5×5の魔方陣を作成するという課題なのですが、手順があります。

(1)配列を用意する

(2)配列を初期化(0クリア)する。

(3)配列添字にスタート位置をセットする。

(4)法則に従い、配列に魔方陣データをセットする

(5)配列を画面に表示する
 (二重ループ)

以上です。わかる方がいたらお手数ですが、ソースコードだけでいいので、教えてください。

お願いします。

Aベストアンサー

> このようなニーズが多いので、宿題代行サービスが、
> 事業として成り立つなら、それもよいかと考えています。

私も同様のことを考えたことがありますが、
問題の難度が低いと「世の中の答えたくてしょうがない人々」により
回答が無料で与えられてしまいますし、
難度が高いと環境の設定など手間と時間がかかりますし、有料に
するとサポートの問題が出てくるのでかなりの高額になるかと。

でも、単純な言語の文法上の問題で、保障無しということならば、
1日以内に必ず有識者の回答が得られるという条件なら1,000円から
3,000円の範囲で払ってよいかと私は思います。

でも、学生はこんなサービスを利用しないで、この便利なネットを
使って情報収集して問題を自力解決すべきですね。

QC言語で制作するピラミッドアートについて

C言語で制作するピラミッドアートについて
私は今、専門学校に通っています。そこでC言語を習っているのですが、数値を入力し、
その個数分*を一辺とする正方形・三角形・逆三角形・三角旗・ダイヤ型・六角形・星
型などのピラミッドアートを描画する課題が出されました。
二重ループなどを上手く使えば出来ると言われ、教科書なども読みましたが、あまり上
手く理解できず、上手くいかなくて困っています。
どうすれば良いのでしょうか?
何か良い解決策やヒント、またはそれについて詳しい方法が書かれてあるサイトや参考
書がありましたら、教えて下さい。

Aベストアンサー

この問題にかぎらず
できること やさしいことからはじめる
(1)プログラムをつくるまえに 手動入力でテキスト文書としてつくってみる
(2)数値はある値に固定してやってみる
以上のことができないのにプログラム作ったり数値を変化させてできるはずがない
まずメモ帳などでつくってみたらいかがですか
そうすればNo.2の人のアドバイスをいかしやすいと思います

Qアスタリスクで正方形

アスタリスク(*)で正方形を作るプログラムをC言語で書いているのですが関数で描画部分を作ることが出来ません。動かす方法を教えて頂けないでしょうか

#include <stdio.h>

void seihoukei(void);
int no,i,j,cnt;
int main(void)
{
int cnt,i,j;

do{
printf("数字(2-9)を入力して下さい:");
scanf("%d",&cnt);

if(cnt<2||cnt>9){
printf("入力エラーです。もう一度入力して下さい");
}
}while(cnt<2||cnt>9);

for(i=1;i<cnt;i++){
for(j=1;j<=cnt;j++){
seihoukei();
}
}
return 0;
}
void seihoukei(void)
{
j = 1;
while(j <= j){
putchar('*');
j=j+1;
}
putchar('\n');
}

Aベストアンサー

とりあえずwhile(j <= j)は無限ループになります。

for(i=1;i<cnt;i++){
for(j=1;j<=cnt;j++){

でcnt*cntの'*'を書けばいいという意図は見えるのですが
void seihoukei(void)でまたループしてるので何がしたいのかよく分かりません。
またここがなぜwhileなのかも不明
ついでにforの条件式がおかしいです。

とりあえず正方形を書きたいだけであれば。

for(i=1;i<cnt;i++){
for(j=1;j<=cnt;j++){
putchar('*');
}
putchar('\n');
}

でいけると思います。
もし関数にしたいなら

for(i=1;i<cnt;i++){
for(j=1;j<=cnt;j++){
seihoukei();
}
}

をseihoukei(cnt);にして

void seihoukei(int size)
{
int i,j;
for(i=0;i<size;i++){
for(j=0;j<size;j++){
putchar('*');
}
putchar('\n');
}
}

を呼び出す形にすればいいと思いますがとりあえず文法が怪しいのでその辺を注意しながらやるといいです。

とりあえずwhile(j <= j)は無限ループになります。

for(i=1;i<cnt;i++){
for(j=1;j<=cnt;j++){

でcnt*cntの'*'を書けばいいという意図は見えるのですが
void seihoukei(void)でまたループしてるので何がしたいのかよく分かりません。
またここがなぜwhileなのかも不明
ついでにforの条件式がおかしいです。

とりあえず正方形を書きたいだけであれば。

for(i=1;i<cnt;i++){
for(j=1;j<=cnt;j++){
putchar('*');
}
putchar('\n');
}

でいけると思います。
もし関数にしたいなら

for(i=1;i<cnt;i++){
for(j=1;j...続きを読む

Qアスタリスクでダイヤ型を作る

アスタリスクでダイヤ型の形を出力するプログラムを作ったのですが
実行例と比較して形が変になってしまいます。また、関数をif文で作ったのですがそれをfor文while文で実行できる形にするにはどのようにしたらいいのでしょうか?
実行例と私が作ったプログラムの実行データを画像に添付しました。

#include <stdio.h>

int daiya( int i, int j, int Num ){
if( j<= i+Num && j<=-i+Num &&
j>= i-Num && j>=-i-Num ){
return 1;
}

}

int main(){
int i, j, n;

do{
puts("数字を入力:");
scanf( "%d", &n );

if(n<2||n>9){
printf("入力エラーです。もう一度入力して下さい\n");
}
}while(n<2||n>9);

for( j=-n/2; j<=n/2; j++ ){
for( i=-n/2; i<=n/2; i++ ){
if( daiya( i, j, n/2 ) == 1 ){
putchar('*');
}
else {
putchar(' ');
}
}
putchar('\n');
}

return 0;
}

アスタリスクでダイヤ型の形を出力するプログラムを作ったのですが
実行例と比較して形が変になってしまいます。また、関数をif文で作ったのですがそれをfor文while文で実行できる形にするにはどのようにしたらいいのでしょうか?
実行例と私が作ったプログラムの実行データを画像に添付しました。

#include <stdio.h>

int daiya( int i, int j, int Num ){
if( j<= i+Num && j<=-i+Num &&
j>= i-Num && j>=-i-Num ){
return 1;
}

}

int main(){
int i, j, n;

do{
puts("...続きを読む

Aベストアンサー

#include <stdio.h>

int daiya(int x, int y, int n)
{
return y <= x + n - 1 && y <= -x + n - 1 &&
y >= x - n + 1 && y >= -x - n + 1;
}

int main(void)
{
int n, x, y;

printf("段数:"); scanf("%d", &n);
for (x = -n + 1; x <= n - 1; x++) {
for (y = -n + 1; y <= n - 1; y++) {
putchar(daiya(x, y, n) ? '*' : ' ');
}
putchar('\n');
}
return 0;
}

Qc言語 プログラム ピラミッド

プログラミングについて教えてください

プログラムは
ピラミッドの図形をユーザーが指定した数字で正三角形の
ピラミッドの段数を指定できるプログラムです

例えば「5」と打てば
********* ■
********■■■
******■■■■■
****■■■■■■■
**■■■■■■■■■
このような感じに表示されます
*の部分は空白です

#include<stdio.h>
int main (void)
{
int num,i,j,h;

printf("ピラミッドの高さを入力してください : ");
scanf("%d" ,&num);

for(i=1; i<=num; i++){
for(j=num; j>=i+1; j--){
printf(" ",j);
}
for(h=1; h<=j; h++){

printf("■");
}
printf("\n");
}
return 0;
}

ここまで出来ています、詰まっているのでご教授ください
よろしくお願いします

Aベストアンサー

#include<stdio.h>
int main (void)
{
int num,i,j,h;
int k;

printf("ピラミッドの高さを入力してください : ");
scanf("%d" ,&num);

for(i=1; i<=num; i++){
for(j=num; j>=i+1; j--){
printf(" ",j);
}
for(h=1; h<=2*j-1; h++){
printf("■");
}
printf("\n");
}
return 0;
}

Q偶数次魔方陣のプログラム

偶数次魔方陣の場合、規則性がないと言われていますが、やはりないのでしょうか?
今4次、6次、8次、の三つだけだせれば良いのですが、処理は全て共通という訳にはいかずに、やはりif文やswitch文などで別々に作らなければいけないのでしょうか?
共通があればそのプログラムを、なければ別々のプログラムも参考にさせて頂きたいと考えています。
よろしくお願いします。

Aベストアンサー

「全部求める」わけじゃないと仮定して:
4の倍数次のものは簡単で, かつ規則性もあります.
4の倍数でない偶数次だと面倒. それなりに方法はありますが.

参考URL:http://www.geocities.jp/ikuro_kotaro/koramu/264_magic3.htm

QC言語のfor文問題で・・・

C言語のfor文問題で・・・

わからない問題がありまして・・・

アスタリスクを表示させる問題なのですが・・・

わかる方いたら、ソースコードだけでいいので、教えてくだい、お願いします

ただし、printfで、全てのアスタリスクを表示させるのはNGで、配列も使ってはいけません。

main関数以外の関数は使わないように、お願いします。

(1)

    1段目に*が1つで、 (三角旗型のアスタリスク)  
    2段目に*が2つで、
    3段目に*が3つで、
    4段目に*が2つで、
    5段目に*が1つ。

(2)


  1段目に*が1つで、  
    2段目に*が3つで、
    3段目に*が5つで、    (ダイヤ型のアスタリスク)
    4段目に*が3つで、
    5段目に*が1つ。    


(3)
      1段目に*が2つで、   (六角形型のアスタリスク)
      2段目に*が4つで、
      3段目に*が2つ。
   


以上3問です。

Aベストアンサー

「ソースコードだけ」っていうじゃなーい、でもそれ「代わりに回答してくれ」って意味ですから、残念。
#我ながら古い。

という訳で方針だけ説明しますが、要は「*の位置決めをどうするか」という話ですね。
ANSIエスケープシーケンスなんて手もなくはないですが、まぁ普通に空白で左から埋めていけばいいでしょう。
「関数」を封じられると#1でも言われているように打つ手なしですが、まぁ本意は「関数を作るな、main()内で完結しろ」って意味でしょうから普通にfor()とputchar()でケースに応じて空白か*を出力するだけです。
一行終わったら改行を出力して次の行、の繰り返し。
配列がNGなのは先に文字列パターンを作って出力するだけ、という手を封じるのが目的でしょうか。
ベタにやってもいいですが、増減値にパターンがあるので各行の空白の数、*の数は計算でも出せなくはありません。

Qピラミッド表示プログラム。

ピラミッドを表示させるプログラムを考えています。

例えば3段の場合

  *
 ***
*****

っというような表示です。

#include <stdio.h>

void spira(int n);

main()
{
int a;

printf("段数は:");
scanf("%d",&a);

spira(a);
}
void spira(int n)
{
int i,j=1,a,b,k;

for(a=n;a>0;a--){
for(b=a-1;b<=n;b--){
printf(" ");
}
k=(j-1)*2+1;
for(i=1;i<=k;i++){
printf("*");
}
j++;
printf("\n");
}
}

このように考えてみたのですが、無限ループになって表示できません。
どこが悪いでしょうか?

無限ループの原因はどうやったら解消されるでしょうか?

Aベストアンサー

yoppiiさんがおっしゃる部分が無限ループの原因だと思います。

この部分を
for(b=1;b>=a-1;b++){

にしてみたらどうでしょう?

Q課題なんですが・・・

プログラムが書いてあるため非常に長文です。
お許しください。
いま、C++でのプログラミング課題が出ているのですが、
正方形の中抜きは出来たのですが、三角形・逆三角形の中抜きが作れません・・・。
もちろん、宿題・課題の丸投げは禁止されているのは分かっています。
しかし、一向に進まないのでなにかヒントだけでも(できたら答えも・・・というのは冗談です)教えていただけないでしょうか。
ちなみに問題は、入力数分の縦×横の図形を描くプログラムを組む。
というものです。

#include <stdio.h>
void main (void)
{
/*変数の宣言*/
int cnt1, cnt2,n;

/*数字の入力*/
do
{
printf("数字2~19を入力してください:");
scanf("%d",&n);
if(n<2 || n>19)
{
printf("入力エラーです!!\nもう一度");
}
}while(n<2 || n>19);


/*正方形の作成*/
printf("\n正方形\n");

for(cnt1=0;cnt1<n;cnt1++)
{
for(cnt2=1;cnt2<=n;cnt2++)
{
printf("*");
}
printf("\n");
}

  printf("\n三角形\n");

for(cnt1=1;cnt1<=n;cnt1++)
{
for(cnt2=0;cnt2<cnt1;cnt2++)
{
printf("*");
}
printf("\n");
}

printf("\n逆三角形\n");

for(cnt1=1;cnt1<=n;cnt1++)
{
for(cnt2=n;cnt2>=cnt1;cnt2--)
{
printf("*");
}
printf("\n");
}

printf("\n三角旗\n");

for(cnt1=1;cnt1<=n;cnt1++)
{
for(cnt2=0;cnt2<cnt1;cnt2++)
{
printf("*");
}
printf("\n");
}
for(cnt1=n-1;cnt1>=0;cnt1--)
{
for(cnt2=0;cnt2<cnt1;cnt2++)
{
printf("*");
}
printf("\n");
}


printf("\nダイヤ形\n");

for(cnt1=1;cnt1<=n;cnt1++)
{
for(cnt2=1;cnt2<=n*2;cnt2++)
{
if(cnt2<=n-cnt1 || cnt2>=n+cnt1)
{
printf(" ");
}
else
{
printf("*");
}
}
printf("\n");
}
for(cnt1=n-1;cnt1>0;cnt1--)
{
for(cnt2=1;cnt2<=n*2;cnt2++)
{
if(cnt2<=n-cnt1 || cnt2>=n+cnt1)
{
printf(" ");
}
else
{
printf("*");
}
}
printf("\n");
}

printf("\n中抜き正方形\n");

for(cnt1=1;cnt1<=n;cnt1++)
{
if(cnt1==1 || cnt1==n)
{
for(cnt2=1;cnt2<=n;cnt2++)
{
printf("*");
}

}
else for(cnt2=1;cnt2<=n;cnt2++)
{
if(cnt2==1 || cnt2==n)
{
printf("*");
}
else
{
printf(" ");
}
}


printf("\n");
}
rewind(stdin);
getchar();
}

プログラムが書いてあるため非常に長文です。
お許しください。
いま、C++でのプログラミング課題が出ているのですが、
正方形の中抜きは出来たのですが、三角形・逆三角形の中抜きが作れません・・・。
もちろん、宿題・課題の丸投げは禁止されているのは分かっています。
しかし、一向に進まないのでなにかヒントだけでも(できたら答えも・・・というのは冗談です)教えていただけないでしょうか。
ちなみに問題は、入力数分の縦×横の図形を描くプログラムを組む。
というものです。

#include <stdi...続きを読む

Aベストアンサー

> かなり高度なものだと思うのですが・・・

まったく通常レベルのものだと思いますけど。。。^^;

> 質問欄にある形式(構文)のみで組むことは出来ませんか?

組むことはできるでしょうね^^

関数呼び出しもダメ、if/while/for だけしか使うな、とか無意味、というより害があると思いますよ(笑)

でもまあ、課題をクリアして、学校を信じてがんばってください。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報