數據結構實驗一實驗二不會的


一、實驗一

1、數組分割

描述

 

已知由n(n≥2)個正整數構成的集合A={ak}(0≤k<n),將其划分為兩個不相交的子集A1和A2,元素個數分別是n1和n2,A1和A2中元素之和分別為S1和S2。設計一個盡可能高效的划分算法,滿足|n1-n2|最小且|S1-S2|最大。

 

輸入

多組數據,每組數據兩行。第一行為一個整數n,代表數組中有n個元素。第二行為數組中的n個元素(元素之間用空格分隔)。當n等於0時,輸入結束。

輸出

每組數據輸出兩行。第一行為子集A1,第二行為子集A2,每兩個元素用空格分隔。

輸入樣例 1 

4
1 2 3 4
5
9 8 1 1 1
0

輸出樣例 1

1 2
3 4
1 1
1 8 9
#include <iostream>
#include <cstdlib>
using namespace std;
int k;
void SetArray(int* data, int size)
{
    for (int i = 0; i < size; i++)
    {
        cin >> data[i];
    }
}

void Print(int* data, int size)
{
    for (int i = 0; i < size; i++) {
        cout << data[i] << " ";
    }
    cout << endl;
}

void FindMax(int* data, int size)
{
    int low = 0, high = size - 1;
    int low0 = 0, high0 = size - 1;
     k = size / 2;
    bool flag = true;
    while (flag) 
    {
        int pivot = data[low];    
        while (low < high) 
        {
        
            while (low < high && data[high] >= pivot)
            {
                high--;
            }
            if (low != high)
            {
                data[low] = data[high];
            }
        
            while (low < high && data[low] <= pivot)
            {
                low++;
            }
            if (low != high)
            {
                data[high] = data[low];
            }
        }
            data[low] = pivot;
            if (low == k - 1) 
                flag = false;
            }
            else if (low < k - 1) {
                low0 = ++low;
                high = high0;
            }
            else {
                high0 = --high;
                low = low0;
            }
        }
    }

int main()
{
    int size, *data;
    while (cin >> size && size != 0)
    {
        data = new int[size];
        SetArray(data, size);
        FindMax(data, size);
        int i;
        for (i = 0; i <k-1; i++)
            cout << data[i] << " ";
        cout << data[i] << endl;
        int j;
        for (j = k; j < size-1; j++)
            cout << data[j] << " ";
        cout << data[j] << endl;
    }
    return 0;
}

2、

基於鏈表的兩個一元多項式的基本運算
 

描述

 

給定兩個一元多項式A(x)與B(x),利用鏈表表示A(x)與B(x),實現A(x)與B(x)的加法、減法、

乘法和求導運算。

 

輸入

輸入多組數據,總計n*( a+b+2)+1行。其中,第一行整數n代表總計有n組數據,之后依次輸入 n組數據。每組數據包括a+b+2行,其中第一行是兩個整數a和b,分別代表A(x)與B(x)的項數。 之后緊跟a行,每行兩個整數a1和a2,分別代表A(x)每項的系數和指數,再之后緊跟b行,每行 兩個整數b1和b2,分別代表B(x)每項的系數和指數,每組數據最后一行為一個字符(+、-、* 、'),分別代表多項式的加法、減法、乘法和求導運算。所有數據的絕對值小於100,指數大 於等於0。

輸出

對於每組數據輸出一行,按照多項式次數從大到小排列,參考格式:5x^17+22x^7+11x^1+7。

輸入樣例 1 

4
1 1
1 0
1 1
+
4 3
7 0
3 1
9 8
5 17
8 1
22 7 
-9 8
+
1 1
1 1
1 1
-
1 1
1 1
1 1
'

輸出樣例 1

1x^1+1
5x^17+22x^7+11x^1+7
0
1
1
#include<iostream>
using namespace std;
typedef struct LNode* List;
struct LNode {
    int coef;//系數
    int exp;//指數
    List next;
};
void InitList(List &L)
{
    L = new LNode;
    L->next = NULL;
}
void CreatList(List &L,int a)//創建鏈表的時候從大到小創建
{
    List p,r;
    p = new LNode;
    L = new LNode;
    L->next = NULL;
    r = L;
    if (a == 0)
    {
        cin>>p->coef;
        cin>>p->exp;
        return;
    }
    for (int i = 0; i < a; i++)
    {
        int m, n;
        p = new LNode;
        cin >> m >> n;
        p->coef = m;
        p->exp = n;
        List q = L;
        while (q->next)
        {
            if (q->next->exp < p->exp)
                break;
            q = q->next;
        }
        p->next = q->next;
        q->next = p;
    }
}
List Add(List &La, List &Lb)
{
    List pa, pb, pc;
    pa = La->next;
    pb = Lb->next;
    pc = La;
    while (pa&&pb)
    {
        if (pa->exp > pb->exp)
        {
            pc->next = pa;
            pa = pa->next;
            pc = pc->next;
        }
        else
            if (pa->exp < pb->exp)
            {
                pc->next = pb;
                pb = pb->next;
                pc = pc->next;
            }
            else
            {
                int sum = pa->coef + pb->coef;
                if (sum != 0)
                {
                    pa->coef = sum;
                    pc->next = pa;
                    pc = pc->next;
                    pa = pa->next;
                    List q = pb;
                    pb = pb->next;
                    free(q);
                }
                else
                {
                    List q = pa;
                    pa = pa->next;
                    free(q);
                    q = pb;
                    pb = pb->next;
                    free(q);
                }
            }
    }
    pc->next = pa ? pa : pb;
    free(Lb);
    return La;
}
List Sub(List La, List Lb)
{
    int sum;
    List pa, pb, pc;
    pa = La->next;
    pb = Lb->next;
    pc = La;
    while (pa&&pb)
    {
        if (pa->exp > pb->exp)
        {
            pc->next = pa;
            pa = pa->next;
            pc = pc->next;
        }
        else
            if (pa->exp < pb->exp)
            {
                pc->next = pb;
                pb = pb->next;
                pc = pc->next;
            }
            else
            {
                sum = pa->coef - pb->coef;
                if (sum)
                {
                    pa->coef = sum;
                    pc->next = pa;
                    pc = pa;
                    pa = pa->next;
                    List q = pb;
                    pb = pb->next;
                    free(q);
                }
                else
                {
                    List q = pa;
                    pa = pa->next;
                    free(q);
                    q = pb;
                    pb = pb->next;
                    free(q);
                }
            }
    }
    if (pa)
    {
        pc->next = pa;
    }
    else
    {
        while (pb)
        {
            pb->coef = -1 * pb->coef;
            pc->next = pb;
            pc = pc->next;
            pb = pb->next;
        }
        pc->next = NULL;
    }
    free(Lb);
    return La;
}
void Print(List L)
{
    List p;
    if (!L)
    {        
        cout << "0" << endl;
         return;
    }
    p = L->next;
    int first = 1;
    while(p)
    {
        if (first)
        {
            first = 0;
        }
        else
        {
            if (p->coef > 0)//負數就有負號了
                cout<<"+";
        }
        if (p->exp == 0)
            cout << p->coef;
        else
            cout << p->coef << "x^" << p->exp;
        p = p->next;
    }
    if (first)
        cout << "0" << endl;
    else
        cout << endl;
}
List Mul(List &La,List &Lb)
{
    List pa = La->next;
    List pb = Lb->next;
    if (!pa || !pb)
    {
        return NULL;
    }
    List Lc;
    InitList(Lc);
    List pc = new LNode;
    pc->coef = pa->coef*pb->coef;
    pc->exp = pa->exp + pb->exp;
    pc->next = NULL;
    Lc->next = pc;
    int n = 1;
    while (pa)
    {
        pb = Lb->next;
        while (pb)
        {
            List pnew =new LNode;
            pnew->coef= pa->coef*pb->coef;
            pnew->exp = pa->exp + pb->exp;
            pnew->next = NULL;
            List p = Lc;
            while (p->next)
            {
                if (pnew->exp == p->next->exp)
                {
                    if (n == 1)
                        break;
                    else
                    {
                        p->next->coef += pnew->coef;
                        n++;
                        break;
                    }
                }
                else
                    if (pnew->exp < p->next->exp)
                    {
                        if (p->next->next == NULL)
                        {
                            p->next->next = pnew;

                            n++;
                            break;
                        }
                        else
                        {
                            p = p->next;//如果不是空的,就繼續和下一個比較
                        }

                    }
                    else
                        if (pnew->exp > p->next->exp)
                        {
                            pnew->next = p->next;
                            p->next = pnew;
                            n++;
                            break;
                        }

            }
            pb = pb->next;
        }
        pa = pa->next;
    }
    return Lc;
}
List Der(List &L)
{
    List p = L;
    while (p->next)
    {
        if (p->next->exp == 0)
        {
            if (p->next->next == NULL)
            {
                p->next->exp = 0;
                p->next->coef = 0;
                return L;
            }
            List q = p->next;
            p->next = q->next;
            delete q;
        }
        else
        {
            p->next->coef *= p->next->exp;
            p->next->exp--;
        }
        p = p->next;
    }
    return L;
}//求導

int main()
{
    int n;
    cin >> n;
    char op;
    for (int i = 0; i < n; i++)
    {
        List La, Lb;
        int a, b;
        cin >> a >> b;//a是A(x)的項數
        if(a==0)
        InitList(La);
        InitList(Lb);
        CreatList(La, a);
        CreatList(Lb, b);
        List c1, c2;
        cin >> op;
        switch (op)
        {
        case '+':
        {
            c1 = Add(La, Lb);
            Print(c1);
            break;
        }
        case '-':
        {
            c1 = Sub(La, Lb);
            Print(c1);
            break;
        }
        case'*':
        {
            c1 = Mul(La, Lb);
            Print(c1);
            break;
        }

        case'\'':
        {
            c1 = Der(La);
            Print(c1);
            c2 = Der(Lb);
            Print(c2);
            break;
        }
        }
    }
    return 0;
}

二、實驗二

1、

Ackermann函數的非遞歸求值
 

描述

 

已知Ackermann函數定義如下:                    

                                                               G]505M1)VF}V{]~U@~SSSMS.png            

寫出計算Ack(m,n)的非遞歸算法。

 

輸入

多組數據,每組數據有一行,為兩個整數m和n。當m和n都等於0時,輸入結束。

輸出

每組數據輸出一行,為Ack(m,n)。

輸入樣例 1 

2 1
0 0

輸出樣例 1

5
#include<iostream>
using namespace std;
int a[200][200];
int main()
{
    int n, m;
    for (int i = 0; i <= 200; i++)
    {

        a[0][i] = i + 1;

    }
    for (int j = 1; j <= 200; j++)//m>0
    {
        a[j][0] = a[j - 1][1];
        for (int i = 1; i <= 200; i++)
        {
            a[j][i] = a[j - 1][a[j][i - 1]];
        }
    }
    while (cin >> m >> n && (n != 0 || m != 0))
    {
        cout << a[m][n] << endl;
    }
    return 0;
}

2、

迷宮問題
 

描述

 

密密被困在一個迷宮里,迷宮有n個路口,編號為1-n。密密現在站在第一個路口,出口編號為m。先給出每個路口通向何處,問密密能否逃出迷宮。

 

輸入

多組數據,每組數據n+2行。第一行為一個正整數n代表路口的個數,之后n行,這n行中的第i行為第i個路口的向左路口、向前路口、向右路口。最后一行為一個正整數m代表迷宮的終點。當n=0時輸入結束。

輸出

每組數據輸出一行,若密密能走出迷宮,輸出“YES”,否則輸出“NO”。

輸入樣例 1 

6
0 2 0
3 5 6
0 0 4
0 0 0
0 0 0
7 0 0
7
3
2 0 0
0 0 0
0 0 0
3
0

輸出樣例 1

YES
NO
#include<iostream>
#include<string>
#include<cstring>
using namespace std;//dfs
int flag;
int p[3];
int a[200][200];
void Dfs(int n,int m)//起點,終點
{
    if (n == m)
    {
        flag = 1;
        return;
    }
    for (int i = 0; i < 3; i++)
    {
        if (a[n][i] && !p[a[n][i]])
        {
            p[a[n][i]] = 1;
            Dfs(a[n][i], m);
            p[a[n][i]] = 0;//???
        }
    }
}
int main()
{
    int n;
    int m;
    while (cin >> n && n != 0)
    {
        flag = 0;
        for (int i = 1; i <=n;i++)
        {
            for (int j = 0; j < 3; j++)
            {
                cin >> a[i][j];
            }
        }
        cin >> m;//代表終點
        p[1] = 1;//起點訪問過
        Dfs(1,m);
        if (flag == 1)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;

    }
    return 0;
}

3、

病毒感染監測
 

描述

 

醫學研究者最近發現了某些新病毒,通過對這些病毒的分析,得知它們的DNA序列都是環狀的。現在研究者收集了大量的病毒DNA和人的DNA數據,想快速檢測出這些人是否感染了相應的病毒。為方便研究,研究者將人的DNA和病毒的DNA均表示成由一些小寫字母組成的字符串,然后檢測某種病毒的DNA序列是否在患者的DNA序列中出現過,如果出現過,則此人感染了病毒,否則沒有感染。注意:人的DNA序列是線性的,而病毒的DNA序列是環狀的。

 

輸入

多組數據,每組數據有一行,為序列A和B,A對應病毒的DNA序列,B對應人的DNA序列。A和B都為“0”時輸入結束。

輸出

對於每組數據輸出一行,若患者感染了病毒輸出“YES”,否則輸出“NO”。

輸入樣例 1 

abbab abbabaab
baa cacdvcabacsd
abc def   
0 0

輸出樣例 1

YES
YES
NO
#include<iostream>
#include<string>
#include<cstring>
using namespace std;//s的第一個字符和t比較,不相等就和第二個比較,如果一旦有不相等的就繼續比較,設置一個標記,如果一直沒有就更新一下s的順序

void change(string &s,int &count)
{
    int length;
    length = s.size();
    char a = s[0];
    for (int i = 1; i < length; i++)
    {
        s[i - 1] = s[i];
    }
    s[length - 1] = a;
    count++;
}
bool Judge(string s, string t)
{
    int flag=0;
    int count=0;//當count比s的長度大的時候,如果依然沒找到就輸出no;
    int length = s.size();
    int ll = t.size();
    while (1)
    {
            int i=0, j = 0;
            int tt = 0;
            while (j!=ll)
            {
                if (s[i] == t[j])
                {
                    i++;
                    j++;
                    if (i-1== 0)
                    {
                        tt = j-1;
                        continue;
                    }
                    if (i-1== length - 1)
                    {
                        flag = 1;
                        break;
                    }
                }
                else
                    if (s[i] != t[j])
                    {
                        if (i == 0)
                        {
                            j++;
                            continue;
                        }
                        else  
                            if (i != 0)
                            {
                                i = 0;
                                j = tt + 1;
                                continue;
                            }
                    }
            }
            if (flag == 1)
                break;
            else
                if (count < length)
                {
                    
                    change(s, count);
                }
                else
                    break;
    }
    if (flag == 1)
        return true;
    else
        return false;
}
int main()
{
    string s, t;
    while (cin >> s >> t && (s != "0" || t != "0"))
    {
        if (Judge(s, t))
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
        
    }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM