小算法

二叉树的一个演示动画: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 }
蒜头君的新技能

 

 

posted @ 2016-04-17 21:54  clairvoyant  阅读(1159)  评论(2编辑  收藏  举报