CF221A Little Elephant and Function 題解
阿新 • • 發佈:2021-12-21
CF221A Little Elephant and Function 題解
Content
小象有一個序列 \(a_1,a_2,a_3,...,a_n\) (其中 \(a_i=i\))和一個遞迴函式 \(f(x)\)。\(f(x)\) 的操作如下:
- 初始時,\(x=n\)。
- 如果 \(x=1\),退出函式;否則,交換 \(a_{x-1},a_x\),並且遞迴至 \(f(x-1)\)。
現在,小象想知道執行完函式以後序列的結果。
資料範圍:\(1\leqslant n\leqslant 1000\)。
Solution
這道題目由於 \(n\) 很小,我們可以考慮多種做法。
Sol.1 遞迴暴力法
我們可以直接模擬出像題面中的 \(f(x)\) 那樣的遞迴函式,並且直接按照題面所要求的操作模擬,最後輸出結果。
Sol.2 非遞迴暴力法
我們可以發現,它無疑就是從 \(n\) 迴圈到 \(2\),每次就交換罷了,因此,我們可以不需要遞迴,直接用一個迴圈來一次一次交換就好。
Sol.3 更優的解法
我們還可以考慮出更簡單的做法。
我們可以發現,所有的操作完了以後,原來在序列中排在最後的 \(n\) 直接調到了首位,其他的整體往後移了一位。
像這樣:
1 2 3 4 5 6 7 8 9 10 操作1: 1 2 3 4 5 6 7 8 10 9 操作2: 1 2 3 4 5 6 7 10 8 9 操作3: 1 2 3 4 5 6 10 7 8 9 操作4: 1 2 3 4 5 10 6 7 8 9 操作5: 1 2 3 4 10 5 6 7 8 9 操作6: 1 2 3 10 4 5 6 7 8 9 操作7: 1 2 10 3 4 5 6 7 8 9 操作8: 1 10 2 3 4 5 6 7 8 9 操作9: 10 1 2 3 4 5 6 7 8 9 結束。
所以,操作完之後的序列就是 \(n,1,2,3,...,n-1\)。
Code
1
#include <cstdio> #include <algorithm> using namespace std; int n, a[1007]; void f(int x) { if(x == 1) return; swap(a[x - 1], a[x]); f(x - 1); } int main() { scanf("%d", &n); for(int i = 1; i <= n; ++i) a[i] = i; f(n); for(int i = 1; i <= n; ++i) printf("%d ", a[i]); }
2
#include <cstdio>
#include <algorithm>
using namespace std;
int n, a[1007];
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) a[i] = i;
for(int i = n; i >= 2; --i) swap(a[i - 1], a[i]);
for(int i = 1; i <= n; ++i) printf("%d ", a[i]);
}
3
#include <cstdio>
#include <algorithm>
using namespace std;
int n, a[1007];
int main() {
scanf("%d", &n);
printf("%d", n);
for(int i = 1; i < n; ++i) printf(" %d", i);
}