SSDUT 数据结构与算法上机题 [更新中]

写的比较随意,班里同学可以参考一下。找到 hack 数据麻烦告诉我一下,找时间更正。

第三周:

1. 定义一个函数,在一组整型数据中查找数据x,返回查找成功还是失败?分析该函数执行过程中,做了多少次的数据比较?

#include <stdio.h>    //    遍历一下就好了吧
using namespace std;
const int MAXN = 1e5 + 10;
int n[MAXN];

int find(int* n, int len, int x) {
    for (int i = 1; i <= len; i++)
        if (n[i] == x)
            return i;
    return 0;
}

int main () {
    int N, x;
    scanf("%d", &N);
    for (int i = 1; i <= N; i++)
        scanf("%d", n + i);
    scanf("%d", &x);
    printf("%d\n", find(n, N, x));
}

2. 一组整型数据记为a0,a1,...,an-1,请定义一个函数将所有小于a0的数据移动到a0前面.(时间和空间性能最优)

我的理解就是只需要把比 a0 小的数移到它前面就好,不用关心两边的顺序问题

还有就是等于 a0 的数,照题意是只要不夹在小于 a0 的数中间就行吗?也就是说不用挨在一起?

因此如 4,5,1,2,4 这样的数据,转换后是 2,1,4,5,4 。按我的理解不是 hack 数据Orz

具体做法就是双指针,一个在头部,一个在尾部

  • 头指针:从头向尾遍历,遇到大于 a0 的数停止
  • 尾指针:从尾向头遍历,遇到小于 a0 的数停止

当符合 l < r 条件时,每次交换两个指针的值

不符合条件时,说明交换完成。把一开始 a0 (a0 已经不在一开始的头位置,此时一定在后半部分) 和临界值交换便可

因为要追求时间和空间性能的最优,所以这样写

#include <stdio.h>    //不用开辟新的空间,直接用原数组便可。扫一遍就好,线性
using namespace std;
const int MAXN = 1e5 + 10;
int n[MAXN];

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

void sort(int n[], int len) {
    int x = n[0], l = 0, r = len - 1, temp = len - 1;
    while (l < r) {
        while (n[l] < x && l < len && l < r) l ++;
        while (n[r] >= x && r > 0 && l < r) r --;
        if (l == len) return;
        if (l != r) {
            swap(n + l, n + r);
            if (l == 0) temp = r;
                l ++;
                r --;
        }
    }
    if (l > r)
        if (l != 0 && r != len - 1)
            swap(n + temp, n + l);
    if (l == r && l != 0 && r != len - 1) {
        if (n[l] > x) swap(n + temp, n + l);
        else if (n[l] < x) swap(n + temp, n + l + 1);
        else if (n[l] == x) {
            while (n[l] <= x) l ++;
            swap(n + temp, n + l);
        }
    }
}

int main () {
    int N;
    scanf("%d", &N);
    for (int i = 0; i < N; i++)
    scanf("%d", n + i);
    sort(n, N);
    for (int i = 0; i < N; i++)
        printf("%d ", n[i]);
    printf("\n");
    return 0;
}

3. 设整数序列(a0, a1,a2,…,an-1)存储于一维数组A中,编写求解最小值的 递归 程序。

 比较偷懒,直接写了线段树,节点维护区间最小值。建树和查询用递归实现的版本。

#include <stdio.h>
#define min(a,b)    (((a) < (b)) ? (a) : (b))

using namespace std;
const int MAXN=1e5 + 10;
int origin[MAXN], tree[MAXN<<2], lazy[MAXN<<2];

void pushup(int p) {
    tree[p]=min(tree[p << 1], tree[p << 1 | 1]);
}

void build(int p, int l, int r) {
    if (l == r) {
        tree[p] = origin[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    pushup(p);
}

int query(int p, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr)  return tree[p];    //被包含在询问区域内的区间(有效的部分)
    int mid = (l + r) >> 1;
    int temp = 0x3f3f3f;
    if (qr > mid) temp = min(temp,query(p << 1 | 1, mid + 1, r, ql, qr));
    if (ql <= mid) temp = min(temp,query(p << 1, l, mid, ql, qr));
    return temp;
}


int main () {
    int N;
    scanf("%d", &N);
    for (int i = 1; i <= N; i++)
        scanf("%d", origin + i);
    build(1, 1, N);
    printf("%d\n", query(1, 1, N, 1, N));
}

4. 已知两组数据(a0, a1,a2,…,an-1)与(b0, b1,b2,…,bn-1)都是从小到大的排列,请编写一个函数将这两组数据合并成一个从小到大的序列.

#include <stdio.h>
using namespace std;
const int MAXN = 1e5 + 10;
int a[MAXN], b[MAXN], c[MAXN];

void solve(int a[], int b[], int c[], int len) {
    int ptr1 = 0, ptr2 = 0, cnt = 0;
    while (ptr1 < len && ptr2 < len) {
        if (a[ptr1] < b[ptr2]) {
            c[cnt] = a[ptr1];
            cnt ++;
            ptr1 ++;
        }
        else{
            c[cnt] = b[ptr2];
            cnt ++;
            ptr2 ++;
        }
    }
    if (ptr1 == len)
        while (ptr2 < len) {
            c[cnt] = b[ptr2];
            cnt ++;
            ptr2 ++;
        }
    else if (ptr2 == len)
        while (ptr1 < len) {
            c[cnt] = a[ptr1];
            cnt ++;
            ptr1 ++;
        }
}


int main () {
    int N;
    scanf("%d", &N);
    for (int i = 0; i < N; i++)
        scanf("%d", a + i);
    for (int i = 0; i < N; i++)
        scanf("%d", b + i);
    solve(a, b, c, N);
    N *= 2;
    for (int i = 0; i < N; i++)
        printf("%d ", c[i]);
    printf("\n");
}

 

更新中。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章