
以下のコードを再帰を使わない方法でやるにはどうしたらいいですか?
※インデントは全角空白になっています。
#define N(n) (a[n]*100+a[n+1]*10+a[n+2])
#define R(n) (a[n+2]*100+a[n+1]*10+a[n])
char a[9];
void sub(int n)
{
int i;
char c;
if(n == 8){
if(N(0) + N(3) * N(6) == R(6) * R(3) + R(0))
printf("%d%d%d+%d%d%d×%d%d%d = %d%d%d×%d%d%d+%d%d%d\n",
a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8],
a[8], a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0]);
return;
}
for(i = n; i < 9; ++i){
c = a[i], a[i] = a[n], a[n] = c;
sub(n + 1);
c = a[i], a[i] = a[n], a[n] = c;
}
}
int main(void)
{
int i;
for(i = 0; i < 9; ++i)
a[i] = i + 1;
sub(0);
return 0;
}
No.3ベストアンサー
- 回答日時:
何をやろうとしているのかが、今ひとつ解読できないのですが。
こういうのは、言葉で説明していただくと助かるんですが。
単に1から9の9個の数字の順列で、
(1*100+2*10+3)*(4*100+5*10+6)+(7*100+8*10+9)
=(9*100+8*10+7)+(6*100+5*10+4)*(3*100+2*10+1)
である順列を列挙する、ではいけないのでしょうか。
int main(){
for(int a0 = 1; a0 <= 9; a0++){
a[0]=a0;
for(int a1 = 1; a1 <= 9; a1++){
if(a1==a[0])continue;
a[1]=a1;
for(int a2 = 1; a2 <= 9; a2++){
if(a2==a[0] || a2==a[1])continue;
a[2]=a2;
for(int a3 = 1; a3 <= 9; a3++){
if(a3==a[0] || a3==a[1] || a3==a[2])continue;
a[3]=a3;
for(int a4 = 1; a4 <= 9; a4++){
if(a4==a[0] || a4==a[1] || a4==a[2] || a4==a[3])continue;
a[4]=a4;
for(int a5 = 1; a5 <= 9; a5++){
if(a5==a[0] || a5==a[1] || a5==a[2] || a5==a[3] || a5==a[4])continue;
a[5]=a5;
for(int a6 = 1; a6 <= 9; a6++){
if(a6==a[0] || a6==a[1] || a6==a[2] || a6==a[3] || a6==a[4] || a6==a[5])continue;
a[6]=a6;
for(int a7 = 1; a7 <= 9; a7++){
if(a7==a[0] || a7==a[1] || a7==a[2] || a7==a[3] || a7==a[4] || a7==a[5] || a7==a[6])continue;
a[7]=a7;
for(int a8 = 1; a8 <= 9; a8++){
if(a8==a[0] || a8==a[1] || a8==a[2] || a8==a[3] || a8==a[4] || a8==a[5] || a8==a[6] || a8==a[7])continue;
a[8]=a8;
if(N(0) + N(3) * N(6) == R(6) * R(3) + R(0))
printf("%d%d%d+%d%d%d×%d%d%d = %d%d%d×%d%d%d+%d%d%d\n",
a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8],
a[8], a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0]);
} } } } } } } } }
}
9重ループです。
個々の添字ごとにすべての重複しない数字(0-9)を埋めます。
No.2
- 回答日時:
再帰の除去を行うには、以下の方針で行うことになります。
* 関数 sub の中身を無限ループで囲む
* 変数 n や i などの値は、スタックに複数個を格納させる
* ループ内で使用する値はスタックの先頭(front)
* sub 内のループは排除して、無限ループに一本化する
* 再帰呼び出し(call)をスタックへの積み込み(push)に変更
* 再帰からの戻り(return)をスタックからの戻し(pop)に変更
ご提示のソースの場合、
sub(n+1) 後の戻し処理をどう行うかが肝となるでしょう。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
最早開始時間と最遅完了時刻を...
-
【C++】関数ポインタの使い方
-
C言語 エラーの原因がわからな...
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語での奇数の和
-
Haskellで関数を合成しようとす...
-
式は定数値が必要です」という...
-
C言語での引数の省略方法
-
未解決の外部シンボル _printf...
-
CStringの配列要素を関数で受け...
-
「指定されたキャストは有効で...
-
return 1L
-
複数桁10進数の*桁目だけを抽出...
-
任意の文字列のアルファベット...
-
入力された数字を大きい順に並...
-
C言語のプログラム作成について
-
【C++】行列データの読み込み
-
2次元配列とポインタの引数受け...
-
数字列を3桁ごとにカンマで区切...
-
C言語 配列と関数の練習問題
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
#define _CRT_SECURE_NO_WARNIN...
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
【C++】関数ポインタの使い方
-
C言語 エラーの原因がわからな...
-
複数桁10進数の*桁目だけを抽出...
-
return 1L
-
if と配列の組み合わせ
-
ラップ関数とはどんなものですか?
-
式は定数値が必要です」という...
-
数字列を3桁ごとにカンマで区切...
-
実数の整数部,小数部の取得
-
C言語でDxlibを使って3x3の奇数...
-
プログラムについて(UNIX)
-
acceptをalarmでタイムアウトさ...
-
C言語の課題です
-
エラー 添字が付けられた値が、...
-
CStringの配列要素を関数で受け...
-
最早開始時間と最遅完了時刻を...
-
入力された数字を大きい順に並...
おすすめ情報