一、實驗一
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函數定義如下:
寫出計算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; }