10代と話して驚いたこと

c言語の質問です。
5×5の行列で

300 300 300 300 300
300 〇 〇 〇 300
300 〇 1200 〇 300
300 〇 〇 〇 300
300 300 300 300 300
の形の行列を作りたいです。
〇は周り4方向の値を足したものを4で割った値にしたいです。
実際にプログラムを書いた結果が
300 300 300 300 300
300 150 0 150 300
300 0 1200 0 300
300 150 0 150 300
300 300 300 300 300 となりました。

#include <stdio.h>

#define M 5
#define N 5

int main(void) {

/* 4行5列の行列 */
int mat[5][5];
int y, x;

for(y=0;y<5;y++){
for(x=0;x<5;x++){
mat[y][x]=0;
}
}

for(y=2;y<3;y++){
for(x=2;x<3;x++){
mat[y][x]=1200;
}
}


for(y=0;y<5;y++){
for(x=0;x<5;x++){
mat[y][x]=0;
if(x==0 || x == 4 || y==0 || y==4 ){
mat[y][x]=300;

}
}

}
for(y=0;y<5;y++){
for(x=0;x<5;x++){
}
}
for(y=0;y<5;y++){
for(x=0;x<5;x++){
mat[y][x]=0;
if( x==0 || x == 4 || y==0 || y==4 ){
mat[y][x]=300;
}
}
}

for(y=0;y<5;y++){
for(x=0;x<5;x++){
if(x==2&&y==2){
mat[y][x]=1200;
}
}
}

for(y=0;y<5;y++){
for(x=0;x<5;x++){
if( x!=0 && x != 4 && y!=0 && y!=4 && (x!=2&&y!=2)){
mat[y][x]=(mat[y-1][x]+mat[y+1][x]+mat[y][x-1]+mat[y][x+1])/4;
}

}

}

for(y=0;y<5;y++){
for(x=0;x<5;x++){
printf( "%3d ", mat[y][x]);
}
printf("\n");
}
return 0;
}


if分のx=2かつy=2のときの表し方がよくない気がするのですがどこが問題か分かる方いらっしゃいませんか?
また反復計算の反復回数はどうやったら指定できるのですか?
この計算をexcelでやったときとくらべて、〇の値が小さいので反復回数が足りていないと思います。

A 回答 (2件)

この問題



https://oshiete.goo.ne.jp/qa/13693773.html

と全くと言って良い程同じ。
取り立てて新しいモノもないし、これも本質的には「連立方程式を解け」と言う一文で要約出来る。
それだけ。

> この計算をexcelでやったときとくらべて、〇の値が小さいので反復回数が足りていないと思います。

そうじゃなくって、最初に手計算ででも何でも、解を求めてみたらいいじゃない。
「不確かな情報のまま不確かに解く」程無駄な事はない。
上のページでも書いたけど、Maxima辺りを使えば簡単に結果は見れる。

Maxima:
https://maxima.sourceforge.io/

このソフトは方程式を解いてくれる「数式処理システム」と言われるジャンルのソフトウェアで、それこそ大学の数学でも役立ってくれる「大学生の必需品」だ。

実装例:
https://www.ideone.com/kfIGZ2
    • good
    • 0

&& (x!=2&&y!=2)



これだと、括弧の意味がなく、

&& x != 2 && y !=2

と同等で、つまり、x = 2の時や、y = 2の時は偽になるので、mat[y][x]へ代入されません。

なので、1200の上下左右には、値が代入されなくなります。

質問者さんがやりたいのは、x = 2 でかつ y = 2の時に、偽になるような論理式を作ればいいだけです。

必ず収束するのであれば、反復計算は、計算前と、計算後の値が全て変化がないか、近似値の条件に一致すれば終了すればいいと思います。
    • good
    • 0

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


おすすめ情報