小算法
二叉树的一个演示动画:http://www.cs.usfca.edu/~galles/visualization/BST.html
对分查找(O(logN)):
1 int BinarySearch(const ElementType A[], ElementType X, int N) 2 { 3 int Low, Mid, High; 4 5 Low = 0; High = N - 1; 6 while (Low <= Higt) { 7 Mid = (Low + High) / 2; 8 if (A[Mid] < X) 9 Low = Mid + 1; 10 else if (A[Mid] > X) 11 High = MId - 1; 12 else 13 return Mid; 14 } 15 return NotFound; 16 }
欧几里得(求最大公因数):
1 unsigned int Gcd(unsigned int M, unsigned int N) 2 { //if M > N 3 unsigned int Rem; 4 5 while (N > 0) { 6 Rem = M % N; 7 M = N; 8 N = Rem; 9 } 10 return M; 11 }
快速取幂:
1 long int Pow(long int X, unsigned int N) 2 { 3 if (N == 0) 4 return 1; 5 if (N == 1) 6 return X; 7 if (IsEven(N)) 8 return Pow(X * X, N / 2); 9 else 10 return Pow(X * X, N / 2) * X; 11 }
最长子序列和:
1 int MaxSubsequenceSum(const int A[], int N) 2 { 3 int ThisSum, MaxSum, j; 4 5 ThisSum = MaxSum = 0; 6 for (int j = 0; j < N; j++) { 7 ThisSum += A[j]; 8 if (ThisSum > MaxSum) 9 MaxSum = ThisSum; 10 else if (ThisSuhttp://i.cnblogs.com/EditPosts.aspx?opt=1m < 0) 11 ThisSum = 0; 12 } 13 return MaxSum; 14 }
霍纳法则(秦九韶)多项式求和:
1 long long HornerRule(const int A[], int N) 2 { 3 long long Poly = 0; 4 for (int i = N; i >= 0; i--) 5 Poly = X * Poly + A[i]; //A[i] is coefficient 6 return Poly; 7 }
快排:
1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 void quick_sort(int dat[], int l, int r) { 5 int i = l, j =r , mid = dat[r]; 6 do { 7 while (dat[i] < mid) ++i; 8 while (dat[j] > mid) --j; 9 if (i <= j) { 10 swap(dat[i], dat[j]); 11 ++i; --j; 12 } 13 } while (i < j); 14 if (l < j) quick_sort(dat, l, j); 15 if (i < r) quick_sort(dat, i, r); 16 } 17 int main() { 18 int dat[10] = {1, 4, 3, 2, 5, 3, 2, 5, 10, 9}; 19 quick_sort(dat, 0, 9); 20 for (int i = 0; i < 10; ++i) 21 printf("%d ", dat[i]); 22 return 0; 23 }
堆排:
1 #include <iostream> 2 #include <cstdio> 3 #include <queue> 4 using namespace std; 5 priority_queue<int> myHeap; 6 int main() { 7 int n = 5, num[5] = {1, 3, 2, 5, 4}; 8 for (int i = 0; i < n; ++i) { 9 myHeap.push(num[i]); 10 } 11 for (int i = 0; i < n; ++i) { 12 printf("%d\n", myHeap.top()); 13 myHeap.pop(); 14 } 15 return 0; 16 }
快速幂的非递归:
1 long int poww(long int x, long int n) 2 { 3 int result = 1; 4 int base = x; 5 while (n != 0) { 6 if (n&1) 7 result *= base; 8 base *= base; 9 n >>= 1; 10 } 11 return result; 12 }
1 蒜头君有一台神奇的魔法机,它能将输入的序列进行一系列复杂的变换,输出原序列的另一种排列方式。蒜头君十分好奇魔法机的工作原理,终于有一天他尝试着把魔法机拆开研究了。 2 3 通过一系列复杂的演算,蒜头君终于发现了魔法机的工作原理:其实魔法机就是一个栈,根据栈先进后出的性质,每次一个数字进栈或将栈顶元素弹出,由此可以产生不同的出栈序列,出栈序列就是原序列的另一种排列啦。 4 5 在研究完原理后,蒜头君凭借记忆很快就把魔法机组装好了。现在蒜头君想测试下魔法机在组装完成后是否出现问题。首先他将 1 到 N 这 N 个数字依次输入魔法机里,然后随机写下一组序列 a,现在他想知道能否通过魔法机得到序列 a。聪明的你能帮蒜头君算一算吗? 6 7 输入格式: 8 9 输入有两行,第一行是一个正整数 N (1 <= N <= 100),表示输入魔法机序列的长度,第二行是序列 a,共有 N 个整数,表示要得到的目标序列。序列为 1 到 N 的排列,即序列 a 长度为 N,保证序列中的整数都不相同,且整数在区间 [1, N] 内。 10 11 输出格式: 12 13 输出一行。如果能通过魔法机得到序列 a,则输出“YES”,否则输出“NO”。 14 样例输入 15 16 5 17 2 1 5 4 3 18 19 样例输出 20 21 YES 22 23 24 #include<iostream> 25 #include<string> 26 #include<cassert> 27 using namespace std; 28 template<class Type> class Stack { 29 private: 30 Type *urls; 31 int max_size, top_index; 32 public: 33 Stack(int length_input) { 34 urls = new Type[length_input]; 35 max_size = length_input; 36 top_index = -1; 37 } 38 ~Stack() { 39 delete[] urls; 40 } 41 bool push(const Type &element) { 42 if (top_index >= max_size - 1) { 43 return false; 44 } 45 top_index++; 46 urls[top_index] = element; 47 return true; 48 } 49 bool pop() { 50 if (top_index < 0) { 51 return false; 52 } 53 top_index--; 54 return true; 55 } 56 Type top() { 57 assert(top_index >= 0); 58 return urls[top_index]; 59 } 60 bool empty() { 61 if (top_index < 0) { 62 return true; 63 } 64 else { 65 return false; 66 } 67 } 68 }; 69 int main() { 70 int n, a; 71 int ans, count = 0; 72 cin >> n; 73 ans = n; 74 Stack<int> stack(n); 75 76 int temp[n]; 77 for (int i = 0; i < n; ++i) { 78 cin >> a; 79 temp[i] = a; 80 } 81 82 for (int i = 0; i < n; ++i) { 83 stack.push(i+1); 84 while (!stack.empty() && stack.top() == temp[count]) { 85 stack.pop(); 86 count++; 87 } 88 } 89 if (count == ans) { 90 cout << "YES" << endl; 91 } 92 else { 93 cout << "NO" << endl; 94 } 95 return 0; 96 }
1 某天,蒜头君发现计蒜客上的用户名好多都长一样,蒜头君看着差点看晕了。为了区分用户名,蒜头君打算好好地清理清理。他将筛选出用户名一样的用户信息,然后给这些用户发邮件,提醒他们改一改用户名。需要注意的是,蒜头君不分大小写字母,所以他认为两个长度相等,每个字符对应一样的用户名是一样的,例如他认为用户名“jisuanke”和“JiSuanKe”是一样的。 2 3 现在蒜头君手里有 N 个用户名,他想知道哪些用户名是重复的。蒜头君按从前往后的顺序依次查看,如果用户名在前面出现过则输出“Yes”,否则输出“No”。现在蒜头君想请你帮他完成这项艰巨的任务,聪明的你能帮他完成吗? 4 5 输入格式: 6 7 输入第一行是一个正整数 N (1 <= N <= 100000),表示一共有 N 个用户名。接下来有 N 行,每一行是一个用户名,长度不超过 100,均由大写字母和小写字母组成。 8 9 输出格式: 10 11 请按照输入顺序输出,如果用户名在前面出现过则输出“Yes”,否则输出“No”,一行输出一个。 12 样例输入 13 14 5 15 AbC 16 jisuanke 17 abc 18 JiSuanKe 19 Hello 20 21 样例输出 22 23 No 24 No 25 Yes 26 Yes 27 No 28 29 30 31 32 #include <iostream> 33 #include <string> 34 #include <cstring> 35 #include <algorithm> 36 using namespace std; 37 class HashTable { 38 private: 39 string *elem; 40 int size; 41 public: 42 HashTable() { 43 size = 200005; 44 elem = new string[size]; 45 for (int i = 0; i < size; i++) { 46 elem[i] = "#"; 47 } 48 } 49 ~HashTable() { 50 delete[] elem; 51 } 52 int hash(string& index) { 53 int code = 0; 54 for (size_t i = 0; i < index.length(); i++) { 55 code = (code * 256 + index[i] + 128) % size; 56 } 57 return code; 58 } 59 bool search(string& index, int& pos, int& times) { 60 pos = hash(index); 61 times = 0; 62 while (elem[pos] != "#" && elem[pos] != index) { 63 times++; 64 if (times < size) { 65 pos = (pos + 1) % size; 66 } else { 67 return false; 68 } 69 } 70 if (elem[pos] == index) { 71 return true; 72 } else { 73 return false; 74 } 75 } 76 int insert(string& index) { 77 int pos, times; 78 if (search(index, pos, times)) { 79 return 2; 80 } else if (times < size / 2) { 81 elem[pos] = index; 82 return 1; 83 } else { 84 recreate(); 85 return 0; 86 } 87 } 88 void recreate() { 89 string* temp_elem; 90 temp_elem = new string[size]; 91 for (int i = 0; i < size; ++i) { 92 temp_elem[i] = elem[i]; 93 } 94 int copy_size = size; 95 size *= 2; 96 delete[] elem; 97 elem = new string[size]; 98 for (int i = 0; i < size; ++i) { 99 elem[i] = "#"; 100 } 101 for (int i = 0; i < copy_size; ++i) { 102 if (temp_elem[i] != "#") { 103 insert(temp_elem[i]); 104 } 105 } 106 delete[] temp_elem; 107 } 108 }; 109 int main() { 110 HashTable hashtable; 111 string buffer; 112 int n; 113 cin >> n; 114 for (int i = 1; i <= n; i++) { 115 cin >> buffer; 116 transform(buffer.begin(), buffer.end(), buffer.begin(), ::tolower); 117 int temp_pos, temp_times; 118 if (hashtable.search(buffer, temp_pos, temp_times)) { 119 cout << "Yes" << endl; 120 } else { 121 cout << "No" << endl; 122 } 123 int ans = hashtable.insert(buffer); 124 } 125 return 0; 126 }
1 蒜头君最近在学习二叉树,可是心不在焉的他一会儿就学累了,于是他想休息会儿。蒜头君拿出镜子,对着镜子中的自己各种卖萌。蒜头君无意间看见镜子中出现了一棵二叉树,这不是他刚画的那棵二叉树么,在镜子里怎么左右颠倒了呀。 2 3 蒜头君觉得好神奇,现在蒜头君又随手画了一棵二叉树,他想知道这棵二叉树在镜子里是长什么样的。为了将问题简单,现在蒜头君告诉你这棵二叉树的先序遍历结果和中序遍历结果,求原始二叉树的后序遍历结果,以及镜子里的二叉树的后序遍历结果。 4 5 输入格式: 6 7 输入第一行是一个字符串 pre_str,代表原始二叉树的先序遍历结果;输入第二行是一个字符串 in_str,代表二叉树的中序遍历结果。每个字符代表结点的编号,结点的编号互不相同,字符仅由大小写字母组成。保证两个字符串长度相等,长度最大不超过 50,且保证可以通过先序遍历结果和中序遍历结果构造出一棵唯一的二叉树。 8 9 输出格式: 10 11 输出第一行,输出一个字符串,代表原始二叉树的后序遍历结果; 12 13 输出第二行,输出一个字符串,代表镜子里的二叉树的后序遍历结果。 14 样例输入 15 16 abdce 17 dbaec 18 19 样例输出 20 21 dbeca 22 ecdba 23 24 25 26 27 #include<iostream> 28 #include<string> 29 using namespace std; 30 class Node { 31 public: 32 int data; 33 Node *lchild, *rchild; 34 Node(int _data) { 35 data = _data; 36 lchild = NULL; 37 rchild = NULL; 38 } 39 ~Node() { 40 if (lchild != NULL) { 41 delete lchild; 42 } 43 if (rchild != NULL) { 44 delete rchild; 45 } 46 } 47 void postorder() { 48 if (lchild != NULL) { 49 lchild->postorder(); 50 } 51 if (rchild != NULL) { 52 rchild->postorder(); 53 } 54 printf("%c", data+48); 55 } 56 void ppostorder() { 57 if (rchild != NULL) { 58 rchild->ppostorder(); 59 } 60 if (lchild != NULL) { 61 lchild->ppostorder(); 62 } 63 printf("%c", data+48); 64 } 65 Node* build(const string& pre_str, const string& in_str, int len) { 66 Node* p = new Node(pre_str[0]-'0'); 67 int pos = in_str.find(pre_str[0]); 68 if (pos > 0) { 69 p->lchild = build(pre_str.substr(1, pos), in_str.substr(0, pos), pos); 70 } 71 if (len - pos - 1 > 0) { 72 p->rchild = 73 build(pre_str.substr(pos+1), in_str.substr(pos+1), len-pos-1); 74 } 75 return p; 76 } 77 }; 78 class BinaryTree { 79 private: 80 Node *root; 81 public: 82 BinaryTree() { 83 root = NULL; 84 } 85 ~BinaryTree() { 86 if (root != NULL) { 87 delete root; 88 } 89 } 90 BinaryTree(const string& pre_str, const string& in_str, int len) { 91 root = root->build(pre_str, in_str, len); 92 } 93 void postorder() { 94 root->postorder(); 95 } 96 void ppostorder() { 97 root->ppostorder(); 98 } 99 }; 100 int main() { 101 string pre_str, in_str; 102 cin >> pre_str >> in_str; 103 BinaryTree binarytree(pre_str, in_str, in_str.length()); 104 binarytree.postorder(); 105 cout << endl; 106 binarytree.ppostorder(); 107 cout << endl; 108 return 0; 109 }
1 蒜头君刚学会一项新技能——数据结构之二叉排序树。蒜头君想复习下刚学的知识,于是他找来一个序列,从序列第一个数开始,依次插入到二叉排序树里。蒜头君一边回忆刚学的知识,按照左孩子权值小,右孩子权值大的口诀,不一会儿就建立起了一棵二叉排序树。 2 3 现在蒜头君想来考考聪明的你:每个结点的左右孩子权值分别是什么? 4 5 输入格式: 6 7 第一行输入一个正整数 N (1 <= N <= 1000),代表序列里元素个数。 8 9 第二行输入 N 个正整数,代表序列 a 的 N 个元素(0 <= ai <= 10000)。保证序列里的元素值互不相同。 10 11 输出格式: 12 13 请按格式“a(b, c)”,输出引号之间的内容,a 代表每个结点的权值,b 代表其左孩子结点权值,c 代表右孩子结点权值,如果孩子结点为空,则输出“#”代替。一个结点输出一行,按结点的权值从小到大输出。注意输出“,”后面的空格。 14 样例输入 15 16 5 17 2 5 3 1 4 18 19 样例输出 20 21 1(#, #) 22 2(1, 5) 23 3(#, 4) 24 4(#, #) 25 5(3, #) 26 27 #include<iostream> 28 using namespace std; 29 class Node { 30 public: 31 int data; 32 Node *lchild, *rchild, *father; 33 Node(int _data, Node *_father = NULL) { 34 data = _data; 35 lchild = NULL; 36 rchild = NULL; 37 father = _father; 38 } 39 ~Node() { 40 if (lchild != NULL) { 41 delete lchild; 42 } 43 if (rchild != NULL) { 44 delete rchild; 45 } 46 } 47 void insert(int value) { 48 if (value == data) { 49 return; 50 } else if (value > data) { 51 if (rchild == NULL) { 52 rchild = new Node(value, this); 53 } else { 54 rchild->insert(value); 55 } 56 } else { 57 if (lchild == NULL) { 58 lchild = new Node(value, this); 59 } else { 60 lchild->insert(value); 61 } 62 } 63 } 64 Node* search(int value) { 65 if (data == value) { 66 return this; 67 } else if (value > data) { 68 if (rchild == NULL) { 69 return NULL; 70 } else { 71 return rchild->search(value); 72 } 73 } else { 74 if (lchild == NULL) { 75 return NULL; 76 } else { 77 return lchild->search(value); 78 } 79 } 80 } 81 Node* predecessor() { 82 Node *temp = lchild; 83 while (temp != NULL && temp->rchild != NULL) { 84 temp = temp->rchild; 85 } 86 return temp; 87 } 88 Node* successor() { 89 Node *temp = rchild; 90 while (temp != NULL && temp->lchild != NULL) { 91 temp = temp->lchild; 92 } 93 return temp; 94 } 95 void remove_node(Node *delete_node) { 96 Node *temp = NULL; 97 if (delete_node->lchild != NULL) { 98 temp = delete_node->lchild; 99 temp->father = delete_node->father; 100 delete_node->lchild = NULL; 101 } 102 if (delete_node->rchild != NULL) { 103 temp = delete_node->rchild; 104 temp->father = delete_node->father; 105 delete_node->rchild = NULL; 106 } 107 if (delete_node->father->lchild == delete_node) { 108 delete_node->father->lchild = temp; 109 } else { 110 delete_node->father->rchild = temp; 111 } 112 delete delete_node; 113 } 114 bool delete_tree(int value) { 115 Node *delete_node, *current_node; 116 current_node = search(value); 117 if (current_node == NULL) { 118 return false; 119 } 120 if (current_node->lchild != NULL) { 121 delete_node = current_node->predecessor(); 122 } 123 else if (current_node->rchild != NULL) { 124 delete_node = current_node->successor(); 125 } 126 else { 127 delete_node = current_node; 128 } 129 current_node->data = delete_node->data; 130 remove_node(delete_node); 131 return true; 132 } 133 void inorder() { 134 if (lchild != NULL) { 135 lchild->inorder(); 136 } 137 cout << data << "("; 138 if (lchild) { 139 cout << lchild->data; 140 } 141 else { 142 cout << "#"; 143 } 144 cout << "," << " "; 145 if (rchild) { 146 cout << rchild->data; 147 } 148 else { 149 cout << "#"; 150 } 151 cout << ")"<< endl; 152 if (rchild != NULL) { 153 rchild->inorder(); 154 } 155 } 156 }; 157 class BinaryTree { 158 private: 159 Node *root; 160 public: 161 BinaryTree() { 162 root = NULL; 163 } 164 ~BinaryTree() { 165 if (root != NULL) { 166 delete root; 167 } 168 } 169 void insert(int value) { 170 if (root == NULL) { 171 root = new Node(value); 172 } else { 173 root->insert(value); 174 } 175 } 176 bool find(int value) { 177 if (root->search(value) == NULL) { 178 return false; 179 } else { 180 return true; 181 } 182 } 183 bool delete_tree(int value) { 184 return root->delete_tree(value); 185 } 186 void inorder() { 187 root->inorder(); 188 } 189 }; 190 int main() 191 { 192 BinaryTree binarytree; 193 int n, a; 194 cin >> n; 195 while (n--) { 196 cin >> a; 197 binarytree.insert(a); 198 } 199 binarytree.inorder(); 200 return 0; 201 }