图片来源
1373 字
7 分钟
【数据结构】C语言测试题
📢 Annoucnement
- 这场不计分,如果计分会在结束后发博客,如果题目太多会开个仓库发。
- 因为题比较多,每道题都比较简单,所以只大概说说思路。
另外说一下感受吧,我感觉虽然一直训练,但是感觉遇到瓶颈了,越打越乏力,想切几道水题释放释放压力,十道题竟然做了一个多小时,属实不应该。这套题非常基础,如果有一定的底子应该是可以直接秒的。很多题数据范围不给,让用户猜。
函数题
长整数转化成16进制字符串
开一个栈先从低位到高位存一下,然后不断取栈顶存到 p 里面就行。
void f( long int x, char *p ) { if (x == 0) { p[0] = 48, p[1] = 0; return; } int l = 0; if (x < 0) p[l++] = '-', x = -x; char tt[34] = {0}; int len = 0; while (x) { int t = x % 16; char c; if (t < 10) c = t + 48; else c = t - 10 + 'A'; tt[len++] = c; x /= 16; } for (int i = len - 1; i >= 0; --i) p[l++] = tt[i]; p[l] = 0;}数组循环右移
开个临时数组存一下右移之后的结果,然后复制回来,注意 m 可能大于 n,最好先取个模。
void ArrayShift( int a[], int n, int m ) { m %= n; int b[MAXN], i; for (i = 0; i < n - m; ++i) { b[i + m] = a[i]; } for (i = 0; i < m; ++i) { b[i] = a[i + n - m]; } for (i = 0; i < n; ++i) { a[i] = b[i]; }}有序表的增删改查操作
除了二分,上课都讲了,需要灵活应用一下,二分记一下板子就行,我这里二分写挂一次。
int lower_bound(int a[], int value) { int l = 0, r = Count; while (l < r) { int mid = l + r >> 1; if (a[mid] >= value) r = mid; else l = mid + 1; } return l;}
int insert(int a[ ], int value) { int p = lower_bound(a, value); if (a[p] == value) return -1; for (int i = Count; i > p; --i) { a[i] = a[i - 1]; } a[p] = value; Count++; return 0;}
int del(int a[ ], int value) { int p = lower_bound(a, value); if (a[p] != value) return -1; for (int i = p; i < Count - 1; ++i) { a[i] = a[i + 1]; } Count--; return 0;}
int modify(int a[ ], int value1, int value2) { if (a[lower_bound(a, value1)] != value1 || a[lower_bound(a, value2)] == value2) return -1; del(a, value1), insert(a, value2); return 0;}
int query(int a[ ], int value) { int p = lower_bound(a, value); if (a[p] != value) return -1; else return p;}建立学生信息链表
按要求模拟即可。
void input() { int num, score; char name[20]; while (scanf("%d%s%d", &num, name, &score), num) { struct stud_node *cur = malloc(sizeof(struct stud_node)); cur->num = num, cur->score = score; strcpy(cur->name, name); if (!head) head = cur; else tail->next = cur; tail = cur; }}链表逆置
开个变量存一下前驱,顺着遍历一遍,依次把 next 指向前驱。
struct ListNode *reverse( struct ListNode *head ) { struct ListNode *pre = NULL; while (head) { // printf("%p ", head); struct ListNode *tmp = head->next; head->next = pre; pre = head; head = tmp; } return pre;}求自定类型元素序列的中位数
数据量有点大,不能直接暴力,因为他限制 c 语言,只能自己写一个 的排序了,我感觉归并排序好写,就写的归并排序。
ElementType b[MAXN];
void msort(ElementType a[], ElementType b[], int l, int r) { if (l == r) return; int mid = l + r >> 1; msort(a, b, l, mid), msort(a, b, mid + 1, r); int h = l, h1 = l, h2 = mid + 1; while (h1 <= mid && h2 <= r) { if (a[h1] <= a[h2]) b[h++] = a[h1++]; else b[h++] = a[h2++]; } while (h1 <= mid) b[h++] = a[h1++]; while (h2 <= r) b[h++] = a[h2++]; for (int i = l; i <= r; ++i) a[i] = b[i];}
ElementType Median( ElementType A[], int N ) { msort(A, b, 0, N - 1); return A[N / 2];}使用函数输出一个整数的逆序数
参考第一道的思路,甚至比第一道还简单,不用转进制,不断取最后一位加到结果的最后一位即可。
int reverse( int number ) { int res = 0; while (number) { res = res * 10 + number % 10; number /= 10; } return res;}编程题
素数对猜想
如果不会筛法,暴力判素数 理论能过,我代码用的线筛。
#include <stdio.h>#define N 100010
int v[N], prime[N], l;
int main() { int n, res = 0; scanf("%d", &n); for (int i = 2; i <= n; ++i) { if (v[i] == 0) { v[i] = i; if (i - prime[l] == 2) res++; prime[++l] = i; } for (int j = 1; j <= l; ++j) { if (prime[j] > v[i] || prime[j] > n / i) break; v[i * prime[j]] = prime[j]; } } printf("%d\n", res - 1); return 0;}数列求和-加强版
答案非常大,需要高精,但是这道题比较特殊,可以先认为,从低到高第 i 位(从 0 计数)为 a * (n - i),然后模拟一下进位,逆序输出。
#include <stdio.h>#define N 200000
int res[N];
int main() { int a, n; scanf("%d%d", &a, &n); for (int i = 0; i < n; ++i) { res[i] = a * (n - i); } for (int i = 0; i < n * 2; ++i) { res[i + 1] += res[i] / 10; res[i] %= 10; } int f = 0; for (int i = n * 2; i >= 0; --i) { if (res[i]) f = 1; if (f) putchar(res[i] + 48); } if (!f) putchar(48); putchar('\n'); return 0;}乘法口诀数列
按要求模拟即可,但是要注意,行末不能输出空格,会格式错误。
#include <stdio.h>#define N 1000
int a[N];
int main() { int n; scanf("%d%d%d", &a[1], &a[2], &n); for (int i = 1, j = 2; j <= n; ++i) { int t = a[i] * a[i + 1]; if (t < 10) a[++j] = t; else a[++j] = t / 10, a[++j] = t % 10; } for (int i = 1; i <= n; ++i) { if (i == 1) printf("%d", a[i]); else printf(" %d", a[i]); } return 0;}部分信息可能已经过时







