Files
C_code/exercise/31.c
T

119 lines
3.0 KiB
C

// 可随机访问的“栈”,支持按下标 O(1) 访问与快 I/O
// 操作:
// 1 x:压入整数 x
// 2:输出栈顶元素
// 3 i:输出第 i 个元素(从 0 开始)
// 4:弹出栈顶元素
// 约束:操作数最多 5,000,000;执行 3 时保证 i 有效
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 快读整数
static inline int read_int(void) {
int c = getchar();
while (c != EOF && (c == ' ' || c == '\n' || c == '\t' || c == '\r')) c = getchar();
int sign = 1;
if (c == '-') { sign = -1; c = getchar(); }
int x = 0;
while (c >= '0' && c <= '9') { x = x * 10 + (c - '0'); c = getchar(); }
return sign * x;
}
// 快速输出整数并换行
static inline void write_int_ln(int x) {
char buf[32];
char *p = buf + sizeof(buf);
*(--p) = '\n';
unsigned int ux;
if (x < 0) {
ux = (unsigned int)(-(long long)x);
} else {
ux = (unsigned int)x;
}
do {
*(--p) = (char)('0' + (ux % 10));
ux /= 10;
} while (ux);
if (x < 0) *(--p) = '-';
fwrite(p, 1, (size_t)(buf + sizeof(buf) - p), stdout);
}
typedef struct {
int *a;
size_t len;
size_t cap;
} RAStack;
static inline void ras_init(RAStack *s) {
s->len = 0;
s->cap = 1024; // 初始容量
s->a = (int*)malloc(s->cap * sizeof(int));
if (!s->a) {
// 若内存紧张,回退到较小容量以继续运行
s->cap = 16;
s->a = (int*)malloc(s->cap * sizeof(int));
if (!s->a) exit(1);
}
}
static inline void ras_reserve(RAStack *s, size_t need) {
if (need <= s->cap) return;
size_t new_cap = s->cap;
while (new_cap < need) {
// 约 1.5 倍扩容,以便在超大输入时节省内存
new_cap = new_cap + (new_cap >> 1);
if (new_cap < s->cap + 1) new_cap = s->cap + 1; // 避免停滞
}
int *na = (int*)realloc(s->a, new_cap * sizeof(int));
if (!na) {
// 若 1.5 倍失败则尝试翻倍
new_cap = s->cap * 2;
na = (int*)realloc(s->a, new_cap * sizeof(int));
if (!na) exit(1);
}
s->a = na;
s->cap = new_cap;
}
static inline void ras_push(RAStack *s, int x) {
if (s->len == s->cap) ras_reserve(s, s->len + 1);
s->a[s->len++] = x;
}
static inline int ras_top(const RAStack *s) {
return s->a[s->len - 1];
}
static inline int ras_get(const RAStack *s, size_t i) {
return s->a[i]; // 从底部 0 开始计数
}
static inline void ras_pop(RAStack *s) {
--s->len;
}
int main(void) {
RAStack st;
ras_init(&st);
int n = read_int();
for (int k = 0; k < n; ++k) {
int op = read_int();
if (op == 1) {
int x = read_int();
ras_push(&st, x);
} else if (op == 2) {
write_int_ln(ras_top(&st));
} else if (op == 3) {
int i = read_int();
write_int_ln(ras_get(&st, (size_t)i));
} else if (op == 4) {
ras_pop(&st);
}
}
free(st.a);
return 0;
}