ページ 1 / 1
二次元配列を調べ、隔離されたマス(穴)の個数を調べる
Posted: 2011年2月17日(木) 02:13
by 学生A
お初です。
コード:
#include <stdio.h>
void init(); //初期化
int countHole(); //穴の個数カウント
//画面の配列
int array[10][10];
//メイン
int main(void)
{
int i,j,value;
init();
value=countHole(); /* 穴の数をカウントして変数valueに代入 */
//画面表示
for(i=0;i<=9;i++) {
for(j=0;j<=9;j++) {
if (array[j][i]==1) {
printf("■");
} else {
printf("□");
}
}
printf("\n");
}
printf("\n穴の個数:%d個\n",value);
scanf("終わり");
return 0;
}
//初期化
void init() {
int i,j;
//全て0にする
for (i=0;i<=9;i++) {
for(j=0;j<=9;j++) {
array[i][j]=0;
}
}
//特定のマスだけ1にする
array[0][8]=1;
array[1][8]=1;
array[2][8]=1;
array[2][9]=1;
}
int countHole() {
/* ここで穴の個数をカウント */
return 0;
}
上記のようなプログラムを実行すると、
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
■■■□□□□□□□
□□■□□□□□□□
穴の個数:0個
と表示されます。
ここで、左下の隔離されたマス(穴)の数を調べて、変数valueに代入したいのですが、出来ますか?
この場合だと「2個」と表示されるのが期待です。
ただし、調べるときは一番上から調べます。
例えば、
□□□□□□□□□□
■■■■■■■■■■
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
だと下の領域を穴と認識し、「80個」と表示されて欲しいです。(左、下、右端には壁があって、上には無いって感じ?かな)
分かりにくくてすいません。ご教授願います。
Re: 二次元配列を調べ、隔離されたマス(穴)の個数を調べる
Posted: 2011年2月17日(木) 02:16
by 学生A
すいません。サンプルの15行目に全角スペースが紛れ込んでいたようです。正しくは以下です。
コード:
#include <stdio.h>
void init(); //初期化
int countHole(); //穴の個数カウント
//画面の配列
int array[10][10];
//メイン
int main(void)
{
int i,j,value;
init();
value=countHole(); /* 穴の数をカウントして変数valueに代入 */
//画面表示
for(i=0;i<=9;i++) {
for(j=0;j<=9;j++) {
if (array[j][i]==1) {
printf("■");
} else {
printf("□");
}
}
printf("\n");
}
printf("\n穴の個数:%d個\n",value);
scanf("終わり");
return 0;
}
//初期化
void init() {
int i,j;
//全て0にする
for (i=0;i<=9;i++) {
for(j=0;j<=9;j++) {
array[i][j]=0;
}
}
//特定のマスだけ1にする
array[0][8]=1;
array[1][8]=1;
array[2][8]=1;
array[2][9]=1;
}
int countHole() {
/* ここで穴の個数をカウント */
return 0;
}
Re: 二次元配列を調べ、隔離されたマス(穴)の個数を調べる
Posted: 2011年2月17日(木) 03:32
by h2so5
学生A さんが書きました:
ここで、左下の隔離されたマス(穴)の数を調べて、変数valueに代入したいのですが、出来ますか?
この場合だと「2個」と表示されるのが期待です。
ただし、調べるときは一番上から調べます。
私の思いつく方法では、
1.まずマス[0,0]を調べます。
2.そのマスに0が入っていた場合: そのマスに2を代入し、 そのマスの周囲の8マスを同様に調べます
そのマスに0以外が入っていた場合: 何もしません
周囲の8マスに対して、上の1,2を繰り返します。
周囲の8マスに0が無くなるまで繰り返されます。
★□□□□□□□□□ ★・・・調べるマス
□□□□□□□□□□ □・・・0が入っている
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
111□□□□□□
□□1□□□□□□□
2★□□□□□□□□ ★・・・調べるマス
★★□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
111□□□□□□
□□1□□□□□□□
22★□□□□□□□ ★・・・調べるマス
22★□□□□□□□
★★★□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
111□□□□□□
□□1□□□□□□□
・
・
・
2222222222 ★・・・調べるマス
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
222★□□□□□□
111★□□□□□ ←1の場合、その周囲のマスは調べない
□□1□□□□□□□
・
・
・
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
1112222222
□□12222222
このようにすると、隔離されていないマスは全て1か2で埋まるため、
0の個数を調べれば穴の数を出すことができます。
Re: 二次元配列を調べ、隔離されたマス(穴)の個数を調べる
Posted: 2011年2月17日(木) 03:49
by フリオ
穴の定義がよくわからないのですが、
□□□□□□□□□□
■■■■■■■■■■
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
■■■■■■■■■■
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
や、
□■□■□□□□□□
□■□■□□□□□□
□■■■□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
等はどうなるのでしょうか。
Re: 二次元配列を調べ、隔離されたマス(穴)の個数を調べる
Posted: 2011年2月17日(木) 06:50
by 学生A
返信ありがとうございます。
>フリオさん
定義があいまいでしたね。
調べる際は、h2so5さんの通り(0,0)から調べることにします。
また、(0,0)=1となることは無いことにします。
穴の中で更に隔離された場合は、どちらも穴とすることにします。
よって
□□□□□□□□□□
■■■■■■■■■■
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
■■■■■■■■■■
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
は70個
□■□■□□□□□□
□■□■□□□□□□
□■■■□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
は2個となります。
>h2so5さん
ありがとうございます。
ぎりぎり組めそうなので頑張ってみます!
組めたらまた投稿します。
Re: 二次元配列を調べ、隔離されたマス(穴)の個数を調べる
Posted: 2011年2月20日(日) 17:29
by 学生A
出来ました。h2so5さん、フリオさん、ありがとうございます!
コードは以下のようになりました。
コード:
#include <stdio.h>
void init(); //初期化
void fillArray(int targetX,int targetY); //arrayを2で埋める
int isOK(int targetX,int targetY); //調べて良い座標か調べる
//画面の配列
int array[10][10];
//メイン
int main(void)
{
int i,j,value=0;
init();
fillArray(0,0); /* (0,0)から隔離されていないマスを2で埋める */
//画面表示&マスカウント
for(i=0;i<=9;i++) {
for(j=0;j<=9;j++) {
switch (array[j][i]) {
case 0:
printf("□");
value++;
break;
case 1:
printf("■");
break;
case 2:
printf("□");
break;
}
}
printf("\n");
}
printf("\n穴の個数:%d個\n",value);
scanf("終わり");
return 0;
}
//初期化
void init() {
int i,j;
//全て0にする
for (i=0;i<=9;i++) {
for(j=0;j<=9;j++) {
array[i][j]=0;
}
}
//特定のマスだけ1にする
array[0][8]=1;
array[1][8]=1;
array[2][8]=1;
array[2][9]=1;
}
//arrayを2で埋める
void fillArray(int targetX,int targetY) {
//指定された座標が空白かどうか調べる
if (array[targetX][targetY] == 0) {
//その座標に2を代入
array[targetX][targetY] = 2;
if ( isOK( targetX + 1 , targetY ) == 1 ) {
fillArray( targetX + 1 , targetY );
}
if ( isOK( targetX - 1 , targetY ) == 1 ) {
fillArray( targetX - 1 , targetY );
}
if ( isOK( targetX , targetY + 1 ) == 1 ) {
fillArray( targetX , targetY + 1 );
}
if ( isOK( targetX , targetY - 1 ) == 1 ) {
fillArray( targetX , targetY - 1 );
}
}
}
//調べて良い座標か調べる
int isOK(int targetX, int targetY) {
if (targetX > -1 && targetX < 10 && targetY > -1 && targetY < 10) {
if (array[targetX][targetY] == 0) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
return 0;
}
なんか冗長な感じになりましたが(再起処理を初めて書いたので^^; もう少し短く書けるところがあれば教えてください。)、要件は満たしたので解決とします。
Re: 二次元配列を調べ、隔離されたマス(穴)の個数を調べる
Posted: 2011年2月20日(日) 19:04
by non
いいと思います。短くしたいなら、判断の場所(タイミング)と、returnをうまく使うことでしょうか。
たとえば、こうなります。
コード:
void fillArray(int targetX,int targetY) {
if (targetX < 0 || targetX >9 | targetY <0 || targetY >9)
return;
//指定された座標が空白かどうか調べる
if (array[targetX][targetY] != 0)
return;
//その座標に2を代入
array[targetX][targetY] = 2;
fillArray( targetX + 1 , targetY );
fillArray( targetX - 1 , targetY );
fillArray( targetX , targetY + 1 );
fillArray( targetX , targetY - 1 );
}
Re: 二次元配列を調べ、隔離されたマス(穴)の個数を調べる
Posted: 2011年2月20日(日) 21:22
by 学生A
>nonさん
なるほど、別にisOKなどの関数を作らなくても、条件に合致しない場合はreturnして強制終了すれば良い ということですね。
これはもしかすると、再帰処理全般に言えることなのかもしれない・・・ とも思いました。
参考になりました。ありがとうございます。