標籤:總數 bre ret 正確答案 判斷 要求 mat 遞增 out
問題描述
秋天到了,n只猴子採摘了一大堆蘋果放到山洞裡,約定第二天平分。這些猴子很崇拜猴王孫悟空,所以都想給他留一些蘋果。第一隻猴子悄悄來到山洞,把蘋果平均分成n份,把剩下的m個蘋果吃了,然後藏起來一份,最後把剩下的蘋果重新合在一起。這些猴子依次悄悄來到山洞,都做同樣的操作,恰好每次都剩下了m個蘋果。第二天,這些猴子來到山洞,把剩下的蘋果分成n分,巧了,還是剩下了m個。問,原來這些猴子至少採了多少個蘋果。
輸入格式
兩個整數,n m
輸出格式
一個整數,表示原來蘋果的數目
範例輸入
5 1
範例輸出
15621
資料規模和約定
0<m<n<9
分析思路
1.正向思維
猴子為n只,每次要餘下m個蘋果。則蘋果最少為n+m個,蘋果每次增加n個。如:
n = 5, m = 1。則蘋果最少為6,它的可能值為6, 11, 16, 21, 26.....
這樣便可從最少的蘋果數開始依次遞增,每個猴子要對蘋果操作一次,操作都為:
蘋果數 / 猴子數 - 餘數。若一隻猴子實行平分操作後蘋果數不剩下m,則此非要求蘋果數,繼續增加下一個可能的蘋果數。直到滿足則跳出迴圈, 再判斷看此數是否還是餘1,是則是正確答案,輸出。
2.遞推思維
還可以從後往前想,蘋果和猴子的數量相等時蘋果最少。蘋果被分了n+1次,吃了n次,最後還剩下m個。
因此,可以得到公式:
蘋果總數 = n ^ (n + 1) - n * m + m
實現代碼
//1. 正向思維#include <iostream>int main(){ int n, m; std::cin >> n >> m; for(int j = n + m; ; j += n) { int i, sum = j; for(i = 0; i < n; ++i) { if(sum % n != m) break; sum = sum - sum/n - m; } if(i == n && sum % n == m) { std::cout << j; break; } } return 0;}
//2.遞推思維#include <iostream>#include <cmath>int main() { int n, m; std::cin >> n >> m; std::cout << pow(n, n+1) - n * m + m << std::endl; return 0;}
猴子分蘋果