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

 

更新中。。。

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