以下のコードを再帰を使わない方法でやるにはどうしたらいいですか?
※インデントは全角空白になっています。
#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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- その他(プログラミング・Web制作) 十進BASICでの再帰についての質問です。 2 2022/11/18 09:17
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語での引数の省略方法
-
【C++】関数ポインタの使い方
-
「指定されたキャストは有効で...
-
#define _CRT_SECURE_NO_WARNIN...
-
複数桁10進数の*桁目だけを抽出...
-
「{ } で囲むだけ」は正しい?
-
実数の整数部,小数部の取得
-
c言語の配列を使ってサイコロを...
-
if と配列の組み合わせ
-
C言語で行列の積を計算できるよ...
-
入力を待たずにstdinの監視をし...
-
C言語 エラーの原因がわからな...
-
C++でvectorにテキストファイル...
-
ラップ関数とはどんなものですか?
-
数字列を3桁ごとにカンマで区切...
-
return 1L
-
PowerShellがうまくいかない
-
C言語の配列をC++のvectorに高...
-
野球の対戦成績のテーブル表示...
-
部分行列の抜き出し(C言語)
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
複数桁10進数の*桁目だけを抽出...
-
【C++】関数ポインタの使い方
-
C言語 エラーの原因がわからな...
-
c++でテンプレートのコードでわ...
-
(int *)の意味
-
ラップ関数とはどんなものですか?
-
数字列を3桁ごとにカンマで区切...
-
c言語のリダイレクトによる円...
-
比較回数と交換回数表示について
-
実数の整数部,小数部の取得
-
if と配列の組み合わせ
-
構造体の勉強中です 合計点の高...
-
PowerShellがうまくいかない
-
c言語の配列を使ってサイコロを...
-
課題でつまってます・・・
-
C言語のサイコロシミュレート
-
エラー 添字が付けられた値が、...
おすすめ情報