解题思路
这是一道关于序列操作的模拟题。主要思路如下:
-
问题分析:
- 给定一个长度为
的序列
- 在空序列
上进行
次操作
- 每次操作包含两步:
- 将
放入
序列末尾
- 将
序列整体逆置
- 将
- 给定一个长度为
-
优化思路:
- 观察最终序列的规律
- 从后向前每隔两个数输出一个数
- 根据
的奇偶性决定第二部分的起始位置
- 从前向后每隔两个数输出一个数
-
关键点:
- 无需实际构造序列和执行逆置操作
- 直接按照最终位置顺序输出
- 处理好奇偶长度的不同情况
代码
#include <iostream>
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int64_t i, n;
uint64_t a[200000];
std::cin >> n;
// 读入数据
for(i = 0; i < n; i++) {
std::cin >> a[i];
}
// 从后向前输出偶数位置的数
for(i = n - 1; i >= 0; i -= 2) {
std::cout << a[i] << " ";
}
// 根据n的奇偶性决定起始位置
if(n % 2) i = 1;
else i = 0;
// 从前向后输出奇数位置的数
for(; i < n; i += 2) {
std::cout << a[i] << " ";
}
std::cout << std::endl;
return 0;
}
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
int n = Integer.parseInt(br.readLine());
long[] a = new long[n];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i = 0; i < n; i++) {
a[i] = Long.parseLong(st.nextToken());
}
// 从后向前输出偶数位置的数
for(int i = n - 1; i >= 0; i -= 2) {
out.print(a[i] + " ");
}
// 根据n的奇偶性决定起始位置
int start = (n % 2 == 1) ? 1 : 0;
// 从前向后输出奇数位置的数
for(int i = start; i < n; i += 2) {
out.print(a[i] + " ");
}
out.println();
out.flush();
}
}
import sys
input = sys.stdin.readline
print = sys.stdout.write
n = int(input())
a = list(map(int, input().split()))
# 从后向前输出偶数位置的数
for i in range(n-1, -1, -2):
print(f"{a[i]} ")
# 根据n的奇偶性决定起始位置
start = 1 if n % 2 else 0
# 从前向后输出奇数位置的数
for i in range(start, n, 2):
print(f"{a[i]} ")
print("\n")
算法分析
- 算法:模拟
- 时间复杂度:
- 只需要遍历一次序列
- 空间复杂度:
- 只需要存储输入序列