元の質問へのリンク:トピック 1004: [再帰] 牛の物語
答え:
# include<stdio.h>
int fun(int n)
{
if(n<=3) return n;
else return fun(n-1)+fun(n-3);
}
int main()
{
int n;
while(scanf("%d",&n) && n)
printf("%d\n",fun(n));
return 0;
}
分析します:
毎年初めに未経産牛を出産する牛がいました。各未経産牛は4年目から始まり、毎年の初めに未経産牛を出産します。ちょっと懐かしいかな?そうです、この質問はフィボナッチ数列に非常に似ていますが、増分の法則が少し変更されています。
入力が 1 つ、出力が 1 つ、テスト ケースが複数セット、入力 0 から終了、これが最初に明確になるため、ループが使用され、0 が入力されるとループが終了します。
まずこの質問のルールを分析しましょう。
以下に簡単な表を示します。
年 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
牛の頭数 | 1 | 2 | 3 | 4 | 6 | 9 | 13 | 19 | 28 |
何か手がかりはありましたか?そうです、fn=fn-1+fn-3(n>3)です。フィボナッチ数列の公式を覚えていますか? fn=fn-1+fn-2(n>2)。そういえば皆さんもやったことがあるのではないでしょうか?
ここでのトピックでは明らかに再帰メソッドを使用する必要があるため、配列のメソッドを送信することもできますが、誰もがそれを行うために再帰を使用することを試みるべきであることに注意してください。。。
再帰であるため、「繰り返しを見つける」「変化を見つける」「境界を見つける」の 3 つのポイントは切り離すことができません。
(1) 重複の検索: これは再帰中に繰り返される操作の一部です。詳細については、上記の式を参照してください。
(2) 変更の検出: これは再帰中のパラメータの変更であり、上記の式に一緒に含まれます。
(3) 境界を見つける: これは再帰的エスケープの条件です。現時点では上記の式は適用できないため、n<=3 であることは明らかです。
区分関数として記述された形式は次のとおりです。
n 、n<=3
f(n)= (中括弧は付けられません。誰でも見ることになります)
f(n-1)+f(n-3) 、n>3
予防:
(1) テスト ケースのグループが複数あることに注意してください。入力と出力をループする方法を見つけてください。
(2) プログラム動作の終了条件は、0 入力時に終了することに注意してください。
(3) 再帰的メソッドのエスケープ条件は n<=3 であることに注意してください。
参照コード:
# include<stdio.h>
int fun(int n)
{
if(n<=3) return n;
else return fun(n-1)+fun(n-3);
}
int main()
{
int n;
while(scanf("%d",&n) && n)
printf("%d\n",fun(n));
return 0;
}
この質問は C Language Network: 1004 からのものです。
この問題を解決するアイデアは、 C Language Network の 著者Yanhuochenxiaoによって再現されています。