一道思维题 &&递归改循环
思路:
比如5 2
12345--> 1245 从3开始,这时候5变成了1.剩下4512,对应1234.只需要找到现在n-1,k中的数对应原来的编号的映射。
比如1-->3 是1+2 mod 5,4-->1是4+2 mod 5. //大雾
应该是4还原成1,4+k+1(3) mod 5=1 , 1还原成4是1+3 mod 5. 2还原成5是 2+k+1=5 mod n =0.(这里引出下面的问题)
这就形成了递归。
这样递归到最后剩一个数,结果就是这个数。
这样的问题是mod n后,n很大时会有数从0开始,
解决办法1:返回时+1
#include <iostream> using namespace std; int A(int n, int k) { if ( n == 1){ return 1; } else{ return (A(n-1,k)+k)%n+1; } } int main() { int n, k; while (true) { cin >> n; cin >> k; cout << A(n,k); } system("pause"); return 0; }
解决办法2:将所有数-1,最后加一 (假设所有数从0开始,12345-->01234)
#include <iostream> using namespace std; int A(int n, int k) { if ( n == 1){ return 0; } else{ return (A(n-1,k)+k)%n; } } int main() { int n, k; cin >> n; cin >> k; cout << A(n,k+1) + 1; return 0; }
这样栈会溢出(n很大的时候)
改成循环
(解法一)
#include <iostream> using namespace std; int A(int n, int k) { int ans=1,s=1; while(s<n){ s++; ans=ans+k; ans=ans%s; ans++; } return ans; } int main() { int n, k; cin >> n; cin >> k; cout << A(n,k) ; system("pause"); return 0; }
(解法2)
#include <iostream> using namespace std; int A(int n, int k) { int ans=0,s=1; while(s<n){ s++; ans=ans+k; ans=ans%s; } return ans; } int main() { int n, k; cin >> n; cin >> k; cout << A(n,k+1) + 1; system("pause"); return 0; }