下記のプログラム(奇数魔方陣)
について最初の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【奇数+偶数=奇数の証明】 これって間違いですか?

『奇数+偶数=奇数』の証明です。これは間違いでしょうか?

nを自然数とすると、偶数は2n、奇数は2n+1で表せるから、
2n+(2n+1)=4n+1
nは自然数だから、4nは偶数である。
よって4n+1は奇数となり、奇数+偶数=奇数である。

よろしくお願いします。

Aベストアンサー

これでは100点をあげられないなあ。
> nを自然数とすると、偶数は2n、奇数は2n+1で表せるから、
ここでは一般の偶数と奇数を考えているのだから,これではまずい。どうして偶数よりも1だけ大きい奇数しか考えないのか?

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。

Q奇数が生成されないという証明。

a,bは1を除く自然数。
nは自然数。

全てのnに対して

2n-1≠√(a×b+2)

ということは正しいでしょうか?

Aベストアンサー

 No,2のものです。No,2で回答した部分に間違いがあったので訂正します。No,2の回答は削除していただけると嬉しいと思います。
 この問題は、√(a×b+2)が奇数になることはないかを示すということですね。
 2n-1=√(a×b+2) が成り立つかを調べればよいのです。
これを2乗して、右辺を左辺に移項すると4n^2-4n-(1+ab)=0 になります。
 nについて解くとn=1+√(2+ab)/2
つまり、√(2+ab)が整数であれば、この式が成り立ちますので、(ab+2)が平方完成されればOKです。
 回答はNo,1さんのおっしゃるとおりです。確かめてみました。どうやって回答したのか過程が知りたいですね。
 ただ、あてはめまくるというのだったらお世辞にもいい問題にはならないでしょう。
 というわけで、No,2での誤答は失礼いたしました。

Qchar AA[]{"全角文字"};から"全"という一字を取り出したい

 今晩は、Cの初心者です、宜しくお願いします。
 全角文字の入ったchar AA[]{"全角文字"};から"全"という文字一字を取り出す時にAA[0]とかくとエラーになります。
 どのようにしたら取り出せるのでしょう。
 ポインタを使う方法と使わない方法を教えて下さい。
 宜しくお願いします。

Aベストアンサー

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出す必要があります。

>char AA[]={'全','角'};

char AA[]="全角";
とし
>printf("%s%s\n" , AA[0],AA[1] ) ;

printf("%c%c\n" , AA[0],AA[1] ) ;
とすれば、「全」だけを表示する事が可能と思われます。

日本語を文字列で表示する為の文字コードについては
Shift-JISだけでなく、UnicodeやUTF・EUC・JISなどがあります。

もう少し詳しく記載してあるホームページはないか探してみましたが、ちょっと無理でした。

参考URL:http://marupeke296.com/CPP_charUnicodeWideChar.html

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出...続きを読む

Q数学の問題(連続する数の証明)について

中3の女子です。
数学の問題で分からないことがあったので質問します。

「連続する3つの奇数において、最も大きい奇数と真ん中の
和の2乗から最も小さい奇数と真ん中の奇数の和の2乗を
ひいた差は、16でわり切れる」
ことの証明を下記に完成しなさい。

(証明) 整数nを使って、最も小さい奇数を2n-1とする。


この問題の解き方が分かんないので、教えてください。
おねがいします。

Aベストアンサー

「連続する3つの奇数において」「整数nを使って、最も小さい奇数を2n-1とする」だから、

2n-1,2n+1,2n+3を連続する3つの奇数とする。
これ、解りますか?

最も大きい奇数と真ん中の和の2乗
(2n+1+2n+3)^2=(4n+4)^2={4(n+1)}^2=16(n^2+2n+1)=16n^2+32n+16

最も小さい奇数と真ん中の奇数の和の2乗
(2n-1+2n+1)^2=(4n)^2=16n^2

最も大きい奇数と真ん中の和の2乗から最も小さい奇数と真ん中の奇数の和の2乗をひいた差
16n^2+32n+16-16n^2=32n+16=16(2n+1)


日本語が解れば、そのまま数式にするだけで、特に難しいところもなく解けるはずですが、どこが解らなかったのでしょうか?

Qint nII[10] = { 0 }について

久々にCを使ってプログラムを組んでいるのですが、基本的な構文を思い出せず
いくつか教えていただきたく質問させていただきました。

1)配列すべてを初期化するのに、宣言時に

int nII[10] = { 0 };

で大丈夫だった(全ての要素が0で初期化)と記憶しているのですが、間違いないでしょうか?

2)構造体の初期化は

struct tm tm;
memset(&tm, 0, sizeof(struct tm))

で大丈夫でしょうか?

3)構造体の宣言は

typedef struct{
int a;
}HOGE, *LPHOGE;

HOGE st; // <- struct HOGE stと同じ
LPHOGE pst; // <- struct HOGE* pstと同じ

で問題ないでしょうか?

以上、3つ質問になって申し訳ないのですが、よろしくお願いします。

Aベストアンサー

1)OK
2)たぶんOK
3)HOGEという名前の構造体はない(当該の構造体には名前がない)ので、
// 以下のコメント記述が誤っています。ただし、

HOGE st;
LPHOGE pst;
という定義そのものはOK

Qこの証明は間違いですか・・・?

【問】
次の命題を証明せよ。
整数aについて、a^2が奇数ならばaは奇数である。

模試でこれを解いたのですが、不正解になりました。
模範解答は別の証明の仕方だったので、どこが間違っているのかわかりません。教えてください。

aが偶数であると仮定する。すると、aは自然数nを使って、
a=2nと表せる。
a^2=(2n)^2だから、
a^2=4a^2
a^2=2(2a^2)となり、a^2は奇数であると言うことに矛盾する。
よってa^2が奇数ならばaは奇数である。

と書いたのですが・・・

Aベストアンサー

まず、3行目から4行目で右辺のnがaに変わってしまっています
またこれをnに直したとしても、5行目までに証明できたのは、『aが偶数ならa^2も偶数である』ということに過ぎず、『a^2は奇数である』は、そこまでのどこにも前提されていませんので矛盾もしません
5行目で展開すべきだったのは、「『a^2は奇数である』に矛盾する」ではなく「『aが偶数ならa^2も偶数である』の対偶であるから『a^2が奇数ならaも奇数』」ということだと思います

Q&str[n]とpstr + nと&pstr[n]

あるプログラミングの本で

&str[n]
pstr + n
&pstr[n]

は同じだと書いてあり、考えたのですが、
上の二つはstr[n]のアドレスを表しているとしても、
三つ目はstr[n]のポインタのアドレスを表していると思うのですが
どこが間違っているのでしょうか?教えてください。

Aベストアンサー

>本にも突然でてきているのでよくわからないのですが・・・。

よくわからないもの同士が同じかと聞かれても、よくわからないというのが答えです。
本当に、突然出てきているのなら、そんな本は捨てましょう。

Q偶数と奇数の和は奇数になることを説明しなさい

中2の数学の問題です。

問題:
偶数と奇数の和は奇数になることを説明しなさい。

問題集の解答で疑問に思う点がありましたので質問させていただきます。
解答:
m,nを自然数とすると偶数は2m、奇数は2n-1と表せる。
2数の和は、
2m+2n-1=2(m+n)-1
m+nは自然数だから2(m+n)は偶数になり、2(m+n)-1は奇数になる。
よって偶数と奇数の和は奇数である。
(証明終わり)

上記証明でわからない点が2点あります。
(1)m,nをなぜ自然数に限定しているのか。
m,nは一般に整数ではないのでしょうか?中学レベルではマイナスの数も
偶数、奇数が定義できると思うので、私はこのm,nは整数と置くのが正しい
答え方だと思うのですが、いかがでしょうか?

(2)もしm,nが自然数と置くのが正しいとしたとき、奇数を2n+3とおいてしまうと
3(n=1)から始まる奇数になり一般に自然数全体で証明したことにならないの
ではないかという疑問があります。
2m+2n+3=2(m+n+1)+1
このような解答も見かけます。
文字式の計算上は奇数といえますが、nが自然数で奇数を2n+3とおいても
問題ないのでしょうか? 

ご回答よろしくお願いします。   

中2の数学の問題です。

問題:
偶数と奇数の和は奇数になることを説明しなさい。

問題集の解答で疑問に思う点がありましたので質問させていただきます。
解答:
m,nを自然数とすると偶数は2m、奇数は2n-1と表せる。
2数の和は、
2m+2n-1=2(m+n)-1
m+nは自然数だから2(m+n)は偶数になり、2(m+n)-1は奇数になる。
よって偶数と奇数の和は奇数である。
(証明終わり)

上記証明でわからない点が2点あります。
(1)m,nをなぜ自然数に限定しているのか。
m,nは一般に整数ではないのでしょうか?中学レベルではマイナ...続きを読む

Aベストアンサー

(1)についてですが、
負の数や0も、奇数・偶数として考える場合もあるので
m,nは整数としておくことが正解ではあります。

しかしながら、文部科学省が作った中学の教科書などでは
偶数、奇数に「0」や「負の数」を含めず、
自然数のみとして教えています。
なので、m,nを自然数に限定しているものだと考えられます。

Qfp = fopen(argy[1], "r");の[1]の意味は

https://oshiete.goo.ne.jp/qa/8940272.html
 の11行目に
fp = fopen(argv[1], "r");の[1]の意味が分かりません。
試したいのですが、ソフトがうまく動きません
 よろしくお願いいたします。

Aベストアンサー

前の例題も読みました。

大分苦戦しているようですが、配列については理解が進みましたでしょうか?
お答えしますと、最初のパラメータ文字列が代入されています。

古いC言語の約束でして大変有名なものです。

コマンドラインコンソールから実行ファイル名を書いて、
パラメータをスペースで区切って指定したとします。

このパラメータ文字列が[1]以降に入ります。
例として、"test"と言う名前の実行ファイルがあったとします。

例)> test test1 test2 3 4

このようにコマンドラインから入力し実行すると、

argc = 5
argv[0] = "test"
argv[1] = "test1"
argv[2] = "test2"
argv[3] = "3"
argv[4] = "4"

と文字列が入ってきます。

以下はサンプル。

void main( int argc , char *argv[])
{
if( argc < 2 )
{
// パラメータ指定がなかった場合の表示
printf( "test に続けて4つまでパラメータを入力できます\n");
exit(0);
}
if( argc > 5 )
{
 // パラメータが5つ以上あった場合の表示
printf( "5つ以上のパラメータは受け付けません\n");
exit(-1);
}

// 正常ルート
printf( "パラメータの数は%d個ですね?ニヤッ\n", argc-1);
printf( "最初のパラメータは%sでしょ?\n", argv[1]);
printf( "残りはargv[2]以降ですが、面倒なので表示しません\n");
}

と言う具合に、引数を活用できます。argv[0]には、実行ファイル名が入ります。
argc は実行ファイルの名前も含めてカウントされます。

プログラムによっては必要な引数の数が変わりますし、
ユーザーのコマンドラインからの入力ミスなどでパラメータがなかったり、
必要なパラメータが不足していたりしますので、
argcとargvを使って最初にシンタックスエラーチェックをするのが常道です。

実行ファイル名の指定がなく、プログラムが実行されることはないと思われます
から、argcは1以上の値になります。

argc, argvの活用は、
実行コマンドを手打ちで打ち込むコンソール形式でよく用いられる基本的な
アプリケーションの開発手法です。

ご質問の箇所は、
第一パラメータにプログラム内で読み込むファイルのファイル名を指定してるの
でしょう。(よくあります)

しかし、Windowsなどのウィンドウを使用するアプリケーションは、
これとは違っておりますので注意が必要です。
(C言語とは別に、Windowsに特化した開発ノウハウの勉強が必要です)

Windows系で上記の様な基本的なプログラムを作成する場合は、
プロジェクトの作成時に(VisualStudioなどで)コンソールアプリケーション
を選んで作成します。実行時にコンソールが開きます。

Linuxの場合は、コンソールがデフォルトになっているでしょうから、
(特殊な設定がなければ)そのまま作成できます。

テキストエディタでソースを記述し、gcc などでコンパイルします。
実行形式ファイルが出来ていれば、想定どおりの動作をするでしょう。

ファイルの読み込みが出来るようになったら、
ファイルの内容を書き換えて保存したり、
ファイル名を変えたり、
ディレクトリ内のファイルを全て表示したり、
ファイル内に含まれる文字列を検索し、該当するファイルをリストしたりなど、

有用なサンプルプログラムを沢山作って練習します。

ファイルを読み込む先は、char型の配列でバイトサイズのメモリーとして確保
します。メモリーと変数の関係を充分に理解することをお勧めします。
殆どのプログラムは、このメモリーの確保やメモリーサイズの計算と格闘する
場合が多くなるからです。

バイナリー形式のファイル(すべてはバイナリー形式として良いのですが)に
ついて理解が深まった後は、
bmpの画像ファイル、wavなどの音声ファイルをあけて、
これの中身を書き換えて遊びます。

特にwavファイルは、音量の変更や周波数フィルタなども掛けれますので、
メモリ、配列、ファイルの関係を(焦らずに)ゆっくり理解するだけで、
今の知識レベルでも面白いことが沢山出来ます。

以上、ご参考に成れば。

前の例題も読みました。

大分苦戦しているようですが、配列については理解が進みましたでしょうか?
お答えしますと、最初のパラメータ文字列が代入されています。

古いC言語の約束でして大変有名なものです。

コマンドラインコンソールから実行ファイル名を書いて、
パラメータをスペースで区切って指定したとします。

このパラメータ文字列が[1]以降に入ります。
例として、"test"と言う名前の実行ファイルがあったとします。

例)> test test1 test2 3 4

このようにコマンドラインから...続きを読む


人気Q&Aランキング