1. 程式人生 > 其它 >CF221A Little Elephant and Function 題解

CF221A Little Elephant and Function 題解

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);
}