├── Chapter1 └── 1.1.cpp ├── Chapter10 ├── 10.1.cpp ├── 10.2.cpp ├── 10.3.cpp ├── 10.4.cpp ├── 10.5.cpp ├── 10.6.cpp ├── 10.7.cpp ├── 10.8.cpp └── 10.9.cpp ├── Chapter11 ├── 11.1.cpp ├── 11.10.cpp ├── 11.11.cpp ├── 11.2.cpp ├── 11.3.cpp ├── 11.4.cpp ├── 11.5.cpp ├── 11.6.cpp ├── 11.7.cpp ├── 11.8.cpp └── 11.9.cpp ├── Chapter12 ├── 12.1.cpp ├── 12.10.cpp ├── 12.11.cpp ├── 12.2.cpp ├── 12.3.cpp ├── 12.4.cpp ├── 12.5.cpp ├── 12.6.cpp ├── 12.7.cpp ├── 12.8.cpp └── 12.9.cpp ├── Chapter2 ├── 2.1.cpp ├── 2.10.cpp ├── 2.11.cpp ├── 2.2.cpp ├── 2.3.cpp ├── 2.4.cpp ├── 2.5.cpp ├── 2.6.cpp ├── 2.7.cpp ├── 2.8.cpp └── 2.9.cpp ├── Chapter3 ├── 3.1.cpp ├── 3.2.cpp ├── 3.3.cpp ├── 3.4.cpp └── 3.5.cpp ├── Chapter4 ├── 4.1.cpp ├── 4.2.cpp ├── 4.3.cpp ├── 4.4.cpp ├── 4.5.cpp ├── 4.6.cpp └── 4.7.cpp ├── Chapter5 ├── 5.1.cpp ├── 5.2.cpp ├── 5.3.cpp ├── 5.4.cpp ├── 5.5.cpp └── 5.6.cpp ├── Chapter6 ├── 6.1.cpp ├── 6.10.cpp ├── 6.11.cpp ├── 6.12.cpp ├── 6.13.cpp ├── 6.14.cpp ├── 6.2.cpp ├── 6.3.cpp ├── 6.4.cpp ├── 6.5.cpp ├── 6.6.cpp ├── 6.7.cpp ├── 6.8.cpp └── 6.9.cpp ├── Chapter7 ├── 7.1.cpp ├── 7.2.cpp ├── 7.3.cpp ├── 7.4.cpp └── 7.5.cpp ├── Chapter8 ├── 8.1.cpp ├── 8.2.cpp ├── 8.3.cpp └── 8.4.cpp ├── Chapter9 ├── 9.1.cpp ├── 9.2.cpp ├── 9.3.cpp └── 9.4.cpp └── README.md /Chapter1/1.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:A + B 3 | * 题目来源:HDU 1089 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1089 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int main() { 14 | int a, b; 15 | while (scanf("%d%d", &a, &b) != EOF) { 16 | printf("%d\n", a + b); 17 | } 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Chapter10/10.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:二叉树遍历 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/AiKuUTlX 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | struct TreeNode { 15 | char data; 16 | TreeNode* leftChild; 17 | TreeNode* rightChild; 18 | TreeNode(char c): data(c), leftChild(NULL), rightChild(NULL) {} 19 | }; 20 | 21 | TreeNode* Build(int& position, string str) { 22 | char current = str[position++]; //当前字符 23 | if (current== '#') { //返回空树 24 | return NULL; 25 | } 26 | TreeNode* root = new TreeNode(current); //创建新节点 27 | root -> leftChild = Build(position, str); //创建左子树 28 | root -> rightChild = Build(position, str); //创建右子树 29 | return root; 30 | } 31 | 32 | void InOrder(TreeNode* root) { //中序遍历 33 | if (root == NULL) { 34 | return; 35 | } 36 | InOrder(root->leftChild); 37 | printf("%c ", root->data); 38 | InOrder(root->rightChild); 39 | return ; 40 | } 41 | 42 | int main() { 43 | string str; 44 | while (cin >> str) { 45 | int position = 0; //标记字符串处理位置 46 | TreeNode* root = Build(position, str); 47 | InOrder(root); 48 | printf("\n"); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /Chapter10/10.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:二叉树遍历 3 | * 题目来源:华中科技大学复试上机题 4 | * 题目链接:http://t.cn/AiKgDfLU 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | struct TreeNode { 15 | char data; 16 | TreeNode* leftChild; 17 | TreeNode* rightChild; 18 | TreeNode(char c): data(c), leftChild(NULL), rightChild(NULL) {} 19 | }; 20 | 21 | TreeNode* Build(string str1, string str2) { 22 | if (str1.size() == 0) { //返回空树 23 | return NULL; 24 | } 25 | char current = str1[0]; //当前字符 26 | TreeNode* root = new TreeNode(current); //创建新节点 27 | int position = str2.find(current); //寻找切分点 28 | root -> leftChild = Build(str1.substr(1, position), str2.substr(0, position)); 29 | root -> rightChild = Build(str1.substr(position + 1), str2.substr(position + 1)); 30 | return root; 31 | } 32 | 33 | void PostOrder(TreeNode* root) { //后序遍历 34 | if (root == NULL) { 35 | return; 36 | } 37 | PostOrder(root->leftChild); 38 | PostOrder(root->rightChild); 39 | printf("%c", root->data); 40 | return; 41 | } 42 | 43 | int main() { 44 | string str1, str2; 45 | while (cin >> str1 >> str2) { 46 | TreeNode* root = Build(str1, str2); 47 | PostOrder(root); 48 | printf("\n"); 49 | } 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /Chapter10/10.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:二叉排序树 3 | * 题目来源:华中科技大学复试上机题 4 | * 题目链接:http://t.cn/Ai9PAkkv 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | struct TreeNode { 14 | int data; 15 | TreeNode* leftChild; 16 | TreeNode* rightChild; 17 | TreeNode(int x): data(x), leftChild(NULL), rightChild(NULL) {} 18 | }; 19 | 20 | TreeNode* Insert(TreeNode* root, int x, int father) { 21 | if (root == NULL) { //创建新节点 22 | root = new TreeNode(x); 23 | printf("%d\n", father); //输出父节点 24 | } else if (x < root->data) { //插入左子树 25 | root->leftChild = Insert(root->leftChild, x, root->data); 26 | } else { //插入右子树 27 | root->rightChild = Insert(root->rightChild, x, root->data); 28 | } 29 | return root; 30 | } 31 | 32 | int main() { 33 | int n; 34 | while (scanf("%d", &n) != EOF) { 35 | TreeNode* root = NULL; //建立空树 36 | for (int i = 0; i < n; ++i) { //逐个插入 37 | int x; 38 | scanf("%d", &x); 39 | root = Insert(root, x, -1); 40 | } 41 | } 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /Chapter10/10.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:二叉排序树 3 | * 题目来源:华中科技大学复试上机题 4 | * 题目链接:http://t.cn/AiKD0L5V 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | struct TreeNode { 14 | int data; 15 | TreeNode* leftChild; 16 | TreeNode* rightChild; 17 | TreeNode(int x): data(x), leftChild(NULL), rightChild(NULL) {} 18 | }; 19 | 20 | TreeNode* Insert(TreeNode* root, int x) { 21 | if (root == NULL) { //创建新节点 22 | root = new TreeNode(x); 23 | } else if (x < root->data) { //插入左子树 24 | root->leftChild = Insert(root->leftChild, x); 25 | } else if (root->data < x) { //插入右子树 26 | root->rightChild = Insert(root->rightChild, x); 27 | } 28 | return root; 29 | } 30 | 31 | void PreOrder(TreeNode* root) { //前序遍历 32 | if (root == NULL) { 33 | return; 34 | } 35 | printf("%d ", root->data); 36 | PreOrder(root->leftChild); 37 | PreOrder(root->rightChild); 38 | return; 39 | } 40 | 41 | void InOrder(TreeNode* root) { //中序遍历 42 | if (root == NULL) { 43 | return; 44 | } 45 | InOrder(root->leftChild); 46 | printf("%d ", root->data); 47 | InOrder(root->rightChild); 48 | return; 49 | } 50 | 51 | void PostOrder(TreeNode* root) { //后序遍历 52 | if (root == NULL) { 53 | return; 54 | } 55 | PostOrder(root->leftChild); 56 | PostOrder(root->rightChild); 57 | printf("%d ", root->data); 58 | return; 59 | } 60 | 61 | int main() { 62 | int n; 63 | while (scanf("%d", &n) != EOF) { 64 | TreeNode* root = NULL; //建立空树 65 | for (int i = 0; i < n; ++i) { //逐个插入 66 | int x; 67 | scanf("%d", &x); 68 | root = Insert(root, x); 69 | } 70 | PreOrder(root); 71 | printf("\n"); 72 | InOrder(root); 73 | printf("\n"); 74 | PostOrder(root); 75 | printf("\n"); 76 | } 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /Chapter10/10.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:复数集合 3 | * 题目来源:北京邮电大学复试上机题 4 | * 题目链接:http://t.cn/Ai98yYlt 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | struct Complex { 16 | int real; //实部 17 | int imag; //虚部 18 | Complex(int r, int i): real(r), imag(i) {} 19 | bool operator< (Complex c) const { //重载小于号 20 | if (real * real + imag * imag == c.real * c.real + c.imag * c.imag) { 21 | return imag > c.imag; 22 | } else { 23 | return real * real + imag * imag < c.real * c.real + c.imag * c.imag; 24 | } 25 | } 26 | }; 27 | 28 | int main() { 29 | int n; 30 | while (scanf("%d", &n) != EOF) { 31 | priority_queue myPriorityQueue; 32 | while (n--) { 33 | string str; 34 | cin >> str; 35 | if (str == "Pop") { 36 | if (myPriorityQueue.empty()) { 37 | printf("empty\n"); 38 | } else { 39 | Complex current = myPriorityQueue.top(); 40 | myPriorityQueue.pop(); 41 | printf("%d+i%d\n", current.real, current.imag); 42 | printf("SIZE = %d\n", myPriorityQueue.size()); 43 | } 44 | } else { 45 | int a, b; 46 | scanf("%d+i%d", &a, &b); 47 | myPriorityQueue.push(Complex(a, b)); 48 | printf("SIZE = %d\n", myPriorityQueue.size()); 49 | } 50 | } 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Chapter10/10.6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:哈夫曼树 3 | * 题目来源:北京邮电大学复试上机题 4 | * 题目链接:http://t.cn/AiCuGMki 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | int main() { 15 | int n; 16 | while (scanf("%d", &n) != EOF) { 17 | priority_queue, greater > myPriorityQueue; 18 | while (n--) { 19 | int x; 20 | scanf("%d", &x); 21 | myPriorityQueue.push(x); 22 | } 23 | int answer = 0; 24 | while (1 < myPriorityQueue.size()) { 25 | int a = myPriorityQueue.top(); 26 | myPriorityQueue.pop(); 27 | int b = myPriorityQueue.top(); 28 | myPriorityQueue.pop(); 29 | answer += a + b; 30 | myPriorityQueue.push(a + b); 31 | } 32 | printf("%d\n", answer); 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Chapter10/10.7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:查找学生信息 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/AiCuVIuY 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | map student; 15 | 16 | int main() { 17 | int n; 18 | scanf("%d", &n); 19 | getchar(); //吃掉回车 20 | for (int i = 0; i < n; ++i) { 21 | string str; 22 | getline(cin, str); 23 | int position = str.find(' '); //分界点 24 | string key = str.substr(0, position); //学号作为关键字 25 | student[key] = str; //信息作为映射值 26 | } 27 | int m; 28 | scanf("%d", &m); 29 | for (int i = 0; i < m; ++i) { 30 | string key; 31 | cin >> key; 32 | string answer = student[key]; 33 | if (answer == "") { //找不到该学生 34 | answer = "No Answer!"; 35 | } 36 | cout << answer << endl; 37 | } 38 | return 0; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /Chapter10/10.8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:魔咒词典 3 | * 题目来源:浙江大学复试上机题 4 | * 题目链接:http://t.cn/AiCufczt 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | map dictionary; 16 | 17 | int main() { 18 | string str; 19 | while (getline(cin, str)) { 20 | if (str == "@END@") { 21 | break; 22 | } 23 | int position = str.find(']'); //分界点 24 | string key = str.substr(0, position + 1); //魔咒 25 | string value = str.substr(position + 2); //功能 26 | dictionary[key] = value; 27 | dictionary[value] = key; 28 | } 29 | int n; 30 | scanf("%d", &n); 31 | getchar(); //吃掉回车 32 | while (n--) { 33 | string key; 34 | getline(cin, key); 35 | string answer = dictionary[key]; 36 | if (answer == "") { //魔咒或者功能找不到 37 | answer = "what?"; 38 | } else if (answer[0] == '[') { //魔咒需要删除方括号 39 | answer = answer.substr(1, answer.size() - 2); 40 | } 41 | cout << answer << endl; 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /Chapter10/10.9.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:子串计算 3 | * 题目来源:北京大学复试上机题 4 | * 题目链接:http://t.cn/AiCuJtI5 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | int main() { 16 | string str; 17 | while (cin >> str) { 18 | map number; 19 | for (int i = 0; i <= str.size(); ++i) { 20 | for (int j = 0; j < i; ++j) { 21 | string key = str.substr(j, i - j); //每个子串 22 | number[key]++; 23 | } 24 | } 25 | map::iterator it; //定义迭代器 26 | for (it = number.begin(); it != number.end(); ++it) { 27 | if (1 < it->second) { 28 | cout << it->first << " " << it->second << endl; 29 | } 30 | } 31 | } 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter11/11.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:畅通工程 3 | * 题目来源:浙江大学复试上机题 4 | * 题目链接:http://t.cn/AiOvBHj9 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 1000 + 10; 14 | 15 | int father[MAXN]; //父亲结点 16 | int height[MAXN]; //结点高度 17 | 18 | void Initial(int n) { //初始化 19 | for (int i = 0; i <= n; i++) { 20 | father[i] = i; //每个结点的父亲为自己 21 | height[i] = 0; //每个结点的高度为零 22 | } 23 | } 24 | 25 | int Find(int x) { //查找根结点 26 | if (x != father[x]) { //路径压缩 27 | father[x] = Find(father[x]); 28 | } 29 | return father[x]; 30 | } 31 | 32 | void Union(int x, int y) { //合并集合 33 | x = Find(x); 34 | y = Find(y); 35 | if (x != y) { //矮树作为高树的子树 36 | if (height[x] < height[y]) { 37 | father[x] = y; 38 | } else if (height[y] < height[x]) { 39 | father[y] = x; 40 | } else { 41 | father[y] = x; 42 | height[x]++; 43 | } 44 | } 45 | return ; 46 | } 47 | 48 | int main() { 49 | int n, m; 50 | while (scanf("%d", &n) != EOF) { 51 | if (n == 0) { 52 | break; 53 | } 54 | scanf("%d", &m); 55 | Initial(n); //初始化 56 | while (m--) { 57 | int x, y; 58 | scanf("%d", &x); 59 | scanf("%d", &y); 60 | Union(x, y); //合并集合 61 | } 62 | int answer = -1; 63 | for (int i = 1; i <= n; i++) { 64 | if (Find(i) == i) { //集合数目 65 | answer++; 66 | } 67 | } 68 | printf("%d\n", answer); 69 | } 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /Chapter11/11.10.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Instrction Arrangement 3 | * 题目来源:HDU 4109 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4109 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | const int MAXN = 1000 + 10; 18 | const int INF = INT_MAX; 19 | 20 | struct Edge { 21 | int to; //终点 22 | int length; //长度 23 | Edge(int t, int l): to(t), length(l) {} 24 | }; 25 | 26 | vector graph[MAXN]; 27 | int earliest[MAXN]; //最早完成时间 28 | int latest[MAXN]; //最晚完成时间 29 | int inDegree[MAXN]; //入度 30 | 31 | int CriticalPath(int n) { 32 | vector topology; //拓扑序列 33 | queue node; 34 | for (int i = 0; i < n; ++i) { 35 | if (inDegree[i] == 0) { 36 | node.push(i); 37 | earliest[i] = 1; //初始化为1 38 | } 39 | } 40 | int totalTime = 0; //总耗时 41 | while (!node.empty()) { 42 | int u = node.front(); 43 | topology.push_back(u); 44 | node.pop(); 45 | for (int i = 0; i < graph[u].size(); ++i) { 46 | int v = graph[u][i].to; 47 | int l = graph[u][i].length; 48 | earliest[v] = max(earliest[v], earliest[u] + l); 49 | inDegree[v]--; 50 | if (inDegree[v] == 0) { 51 | node.push(v); 52 | totalTime = max(totalTime, earliest[v]); 53 | } 54 | } 55 | } 56 | for (int i = topology.size() - 1; i >= 0; --i) { 57 | int u = topology[i]; 58 | if (graph[u].size() == 0) { 59 | latest[u] = earliest[u]; //汇点的最晚完成时间初始化 60 | } else { 61 | latest[u] = INF; //非汇点的最晚完成时间初始化 62 | } 63 | for (int j = 0; j < graph[u].size(); ++j) { 64 | int v = graph[u][j].to; 65 | int l = graph[u][j].length; 66 | latest[u] = min(latest[u], latest[v] - l); 67 | } 68 | } 69 | return totalTime; 70 | } 71 | 72 | int main() { 73 | int n, m; 74 | while (scanf("%d%d", &n, &m) != EOF) { 75 | memset(graph, 0, sizeof(graph)); 76 | memset(earliest, 0, sizeof(earliest)); 77 | memset(latest, 0, sizeof(latest)); 78 | memset(inDegree, 0, sizeof(inDegree)); 79 | while (m--) { 80 | int from, to, length; 81 | scanf("%d%d%d", &from, &to, &length); 82 | graph[from].push_back(Edge(to, length)); 83 | inDegree[to]++; 84 | } 85 | int answer = CriticalPath(n); 86 | printf("%d\n", answer); 87 | } 88 | return 0; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /Chapter11/11.11.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:P3 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:无 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | const int MAXN = 1e5 + 7; 18 | const int INF = INT_MAX; 19 | const int MOD = 1e9 + 7; 20 | 21 | vector graph[MAXN]; 22 | int inDegree[MAXN]; //入度 23 | long long earliest[MAXN]; //最早完成时间 24 | long long latest[MAXN]; //最晚完成时间 25 | long long time[MAXN]; //花费时间 26 | 27 | long long CriticalPath(int n) { 28 | vector topology; //拓扑序列 29 | queue node; 30 | for (int i = 1; i <= n; ++i) { 31 | if (inDegree[i] == 0) { 32 | node.push(i); 33 | } 34 | } 35 | long long totalTime = 0; //总耗时 36 | while (!node.empty()) { 37 | int u = node.front(); 38 | topology.push_back(u); 39 | node.pop(); 40 | for (int i = 0; i < graph[u].size(); ++i) { 41 | int v = graph[u][i]; 42 | earliest[v] = max(earliest[v], earliest[u] + time[u]); 43 | inDegree[v]--; 44 | if (inDegree[v] == 0) { 45 | node.push(v); 46 | totalTime = max(totalTime, earliest[v] + time[v]); 47 | } 48 | } 49 | } 50 | for (int i = topology.size() - 1; i >= 0; --i) { 51 | int u = topology[i]; 52 | if (graph[u].size() == 0) { 53 | latest[u] = totalTime - time[u]; 54 | } else { 55 | latest[u] = INF; 56 | } 57 | for (int j = 0; j < graph[u].size(); ++j) { 58 | int v = graph[u][j]; 59 | latest[u] = min(latest[u], latest[v] - time[u]); 60 | } 61 | } 62 | return totalTime; 63 | } 64 | 65 | int main() { 66 | int n, m; 67 | while (scanf("%d%d", &n, &m) != EOF) { 68 | memset(graph, 0, sizeof(graph)); 69 | memset(earliest, 0, sizeof(earliest)); 70 | memset(latest, 0, sizeof(latest)); 71 | memset(inDegree, 0, sizeof(inDegree)); 72 | memset(time, 0, sizeof(time)); 73 | for (int i = 1; i <= n; ++i) { 74 | scanf("%lld", &time[i]); 75 | } 76 | while (m--) { 77 | int from, to; 78 | scanf("%d%d", &from, &to); 79 | graph[from].push_back(to); 80 | inDegree[to]++; 81 | } 82 | long long totalTime = CriticalPath(n); 83 | long long answer = 1; 84 | for (int i = 1; i <= n; ++i) { 85 | answer *= latest[i] - earliest[i] + 1; 86 | answer %= MOD; 87 | } 88 | printf("%lld\n%lld\n", totalTime, answer); 89 | } 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /Chapter11/11.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:连通图 3 | * 题目来源:吉林大学复试上机题 4 | * 题目链接:http://t.cn/AiO77VoA 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 1000 + 10; 14 | 15 | int father[MAXN]; //父亲结点 16 | int height[MAXN]; //结点高度 17 | 18 | void Initial(int n) { //初始化 19 | for (int i = 0; i <= n; i++) { 20 | father[i] = i; //每个结点的父亲为自己 21 | height[i] = 0; //每个结点的高度为零 22 | } 23 | } 24 | 25 | int Find(int x) { //查找根结点 26 | if (x != father[x]) { //路径压缩 27 | father[x] = Find(father[x]); 28 | } 29 | return father[x]; 30 | } 31 | 32 | void Union(int x, int y) { //合并集合 33 | x = Find(x); 34 | y = Find(y); 35 | if (x != y) { //矮树作为高树的子树 36 | if (height[x] < height[y]) { 37 | father[x] = y; 38 | } else if (height[y] < height[x]) { 39 | father[y] = x; 40 | } else { 41 | father[y] = x; 42 | height[x]++; 43 | } 44 | } 45 | return ; 46 | } 47 | 48 | int main() { 49 | int n, m; 50 | while (scanf("%d%d", &n, &m) != EOF) { 51 | if (n == 0 && m == 0) { 52 | break; 53 | } 54 | Initial(n); //初始化 55 | while (m--) { 56 | int x, y; 57 | scanf("%d", &x); 58 | scanf("%d", &y); 59 | Union(x, y); //合并集合 60 | } 61 | int component = 0; //连通分量 62 | for (int i = 1; i <= n; i++) { 63 | if (Find(i) == i) { //集合数目 64 | component++; 65 | } 66 | } 67 | if (component == 1) { 68 | printf("YES\n"); 69 | } else { 70 | printf("NO\n"); 71 | } 72 | } 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /Chapter11/11.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Is It A Tree? 3 | * 题目来源:北京大学复试上机题 4 | * 题目链接:http://t.cn/AiO7FyDO 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 1e4 + 10; 14 | 15 | int father[MAXN]; //父亲结点 16 | int height[MAXN]; //结点高度 17 | int inDegree[MAXN]; //入度 18 | bool visit[MAXN]; //标记 19 | 20 | void Initial() { //初始化 21 | for (int i = 0; i < MAXN; i++) { 22 | father[i] = i; 23 | height[i] = 0; 24 | inDegree[i] = 0; 25 | visit[i] = false; 26 | } 27 | } 28 | 29 | int Find(int x) { //查找根结点 30 | if (x != father[x]) { 31 | father[x] = Find(father[x]); 32 | } 33 | return father[x]; 34 | } 35 | 36 | void Union(int x, int y) { //合并集合 37 | x = Find(x); 38 | y = Find(y); 39 | if (x != y) { 40 | if (height[x] < height[y]) { 41 | father[x] = y; 42 | } else if (height[y] < height[x]) { 43 | father[y] = x; 44 | } else { 45 | father[y] = x; 46 | height[x]++; 47 | } 48 | } 49 | return ; 50 | } 51 | 52 | bool IsTree() { 53 | bool flag = true; 54 | int component = 0; //连通分量数目 55 | int root = 0; //根结点数目 56 | for (int i = 0; i < MAXN; ++i) { 57 | if (!visit[i]) { 58 | continue; 59 | } 60 | if (father[i] == i) { 61 | component++; 62 | } 63 | if (inDegree[i] == 0) { 64 | root++; 65 | } else if (inDegree[i] > 1) { //入度不满足要求 66 | flag = false; 67 | } 68 | } 69 | if (component != 1 || root != 1) { //不符合树定义 70 | flag = false; 71 | } 72 | if(component == 0 && root == 0) { //空集也是树 73 | flag = true; 74 | } 75 | return flag; 76 | } 77 | 78 | int main() { 79 | int x, y; 80 | int caseNumber = 0; 81 | Initial(); 82 | while (scanf("%d%d", &x, &y) != EOF) { 83 | if (x == -1 && y == -1) { 84 | break; 85 | } 86 | if (x == 0 && y == 0) { 87 | if (IsTree()) { 88 | printf("Case %d is a tree.\n", ++caseNumber); 89 | } else { 90 | printf("Case %d is not a tree.\n", ++caseNumber); 91 | } 92 | Initial(); 93 | } else { 94 | Union(x, y); 95 | inDegree[y]++; 96 | visit[x] = true; 97 | visit[y] = true; 98 | } 99 | } 100 | return 0; 101 | } 102 | 103 | -------------------------------------------------------------------------------- /Chapter11/11.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:还是畅通工程 3 | * 题目来源:浙江大学复试上机题 4 | * 题目链接:http://t.cn/AiWud0C6 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 100 + 10; 15 | 16 | struct Edge { 17 | int from; //边的起点 18 | int to; //边的终点 19 | int length; //边的长度 20 | bool operator< (const Edge& e) const { 21 | return length < e.length; 22 | } 23 | }; 24 | 25 | Edge edge[MAXN * MAXN]; //边集 26 | int father[MAXN]; //父亲结点 27 | int height[MAXN]; //结点高度 28 | 29 | void Initial(int n) { //初始化 30 | for (int i = 0; i <= n; i++) { 31 | father[i] = i; 32 | height[i] = 0; 33 | } 34 | } 35 | 36 | int Find(int x) { //查找根结点 37 | if (x != father[x]) { 38 | father[x] = Find(father[x]); 39 | } 40 | return father[x]; 41 | } 42 | 43 | void Union(int x, int y) { //合并集合 44 | x = Find(x); 45 | y = Find(y); 46 | if (x != y) { 47 | if (height[x] < height[y]) { 48 | father[x] = y; 49 | } else if (height[y] < height[x]) { 50 | father[y] = x; 51 | } else { 52 | father[y] = x; 53 | height[x]++; 54 | } 55 | } 56 | return ; 57 | } 58 | 59 | int Kruskal(int n, int edgeNumber) { 60 | Initial(n); 61 | sort(edge, edge + edgeNumber); //按权值排序 62 | int sum = 0; 63 | for (int i = 0; i < edgeNumber; ++i) { 64 | Edge current = edge[i]; 65 | if (Find(current.from) != Find(current.to)) { 66 | Union(current.from, current.to); 67 | sum += current.length; 68 | } 69 | } 70 | return sum; 71 | } 72 | 73 | int main() { 74 | int n; 75 | while (scanf("%d", &n) != EOF) { 76 | if (n == 0) { 77 | break; 78 | } 79 | int edgeNumber = n * (n - 1) / 2; 80 | for (int i = 0; i < edgeNumber; ++i) { 81 | scanf("%d%d%d", &edge[i].from, &edge[i].to, &edge[i].length); 82 | } 83 | int answer = Kruskal(n, edgeNumber); 84 | printf("%d\n", answer); 85 | } 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /Chapter11/11.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:继续畅通工程 3 | * 题目来源:浙江大学复试上机题 4 | * 题目链接:http://t.cn/AiW3fcfp 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 100 + 10; 15 | 16 | struct Edge { 17 | int from; //边的起点 18 | int to; //边的终点 19 | int length; //边的长度 20 | bool operator< (const Edge& e) const { 21 | return length < e.length; 22 | } 23 | }; 24 | 25 | Edge edge[MAXN * MAXN]; //边集 26 | int father[MAXN]; //父亲结点 27 | int height[MAXN]; //结点高度 28 | 29 | void Initial(int n) { //初始化 30 | for (int i = 0; i <= n; i++) { 31 | father[i] = i; 32 | height[i] = 0; 33 | } 34 | } 35 | 36 | int Find(int x) { //查找根结点 37 | if (x != father[x]) { 38 | father[x] = Find(father[x]); 39 | } 40 | return father[x]; 41 | } 42 | 43 | void Union(int x, int y) { //合并集合 44 | x = Find(x); 45 | y = Find(y); 46 | if (x != y) { 47 | if (height[x] < height[y]) { 48 | father[x] = y; 49 | } else if (height[y] < height[x]) { 50 | father[y] = x; 51 | } else { 52 | father[y] = x; 53 | height[x]++; 54 | } 55 | } 56 | return ; 57 | } 58 | 59 | int Kruskal(int n, int edgeNumber) { 60 | Initial(n); 61 | sort(edge, edge + edgeNumber); //按权值排序 62 | int sum = 0; 63 | for (int i = 0; i < edgeNumber; ++i) { 64 | Edge current = edge[i]; 65 | if (Find(current.from) != Find(current.to)) { 66 | Union(current.from, current.to); 67 | sum += current.length; 68 | } 69 | } 70 | return sum; 71 | } 72 | 73 | int main() { 74 | int n; 75 | while (scanf("%d", &n) != EOF) { 76 | if (n == 0) { 77 | break; 78 | } 79 | int edgeNumber = n * (n - 1) / 2; 80 | for (int i = 0; i < edgeNumber; ++i) { 81 | int status; 82 | scanf("%d%d%d%d", &edge[i].from, &edge[i].to, &edge[i].length, &status); 83 | if (status == 1) { 84 | edge[i].length = 0; 85 | } 86 | } 87 | int answer = Kruskal(n, edgeNumber); 88 | printf("%d\n", answer); 89 | } 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /Chapter11/11.6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:畅通工程续 3 | * 题目来源:HDU 1874 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1874 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | const int MAXN = 200 + 10; 18 | const int INF = INT_MAX; //无穷设为很大的数 19 | 20 | struct Edge { 21 | int to; //终点 22 | int length; //长度 23 | Edge(int t, int l): to(t), length(l) {} 24 | }; 25 | 26 | struct Point { 27 | int number; //点的编号 28 | int distance; //源点到该点距离 29 | Point(int n, int d): number(n), distance(d) {} 30 | bool operator< (const Point& p) const { 31 | return distance > p.distance; //距离小的优先级高 32 | } 33 | }; 34 | 35 | vector graph[MAXN]; //邻接表实现的图 36 | int minDistance[MAXN]; //源点到各点最短距离 37 | 38 | void Dijkstra(int start) { 39 | minDistance[start] = 0; 40 | priority_queue myPriorityQueue; 41 | myPriorityQueue.push(Point(start, minDistance[start])); 42 | while (!myPriorityQueue.empty()) { 43 | int u = myPriorityQueue.top().number; //离源点最近的点 44 | myPriorityQueue.pop(); 45 | for (int i = 0; i < graph[u].size(); ++i) { 46 | int v = graph[u][i].to; 47 | int l = graph[u][i].length; 48 | if (minDistance[v] > minDistance[u] + l) { 49 | minDistance[v] = minDistance[u] + l; 50 | myPriorityQueue.push(Point(v, minDistance[v])); 51 | } 52 | } 53 | } 54 | return ; 55 | } 56 | 57 | int main() { 58 | int n, m; 59 | while (scanf("%d%d", &n, &m) != EOF) { 60 | memset(graph, 0, sizeof(graph)); //图初始化 61 | fill(minDistance, minDistance + n, INF); //距离初始化为无穷 62 | while (m--) { 63 | int from, to, length; 64 | scanf("%d%d%d", &from, &to, &length); 65 | graph[from].push_back(Edge(to, length)); 66 | graph[to].push_back(Edge(from, length)); 67 | } 68 | int start, terminal; //起点与终点 69 | scanf("%d%d", &start, &terminal); 70 | Dijkstra(start); 71 | if (minDistance[terminal] == INF) { //终点不可达 72 | minDistance[terminal] = -1; 73 | } 74 | printf("%d\n", minDistance[terminal]); 75 | } 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /Chapter11/11.7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:最短路径问题 3 | * 题目来源:浙江大学复试上机题 4 | * 题目链接:http://t.cn/AilPbME2 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | const int MAXN = 1000 + 10; 18 | const int INF = INT_MAX; //无穷设为很大的数 19 | 20 | struct Edge { 21 | int to; //终点 22 | int length; //长度 23 | int price; //花费 24 | Edge(int t, int l, int p): to(t), length(l), price(p) {} 25 | }; 26 | 27 | struct Point { 28 | int number; //点的编号 29 | int distance; //源点到该点距离 30 | Point(int n, int d): number(n), distance(d) {} 31 | bool operator< (const Point& p) const { 32 | return distance > p.distance; //距离小的优先级高 33 | } 34 | }; 35 | 36 | vector graph[MAXN]; //邻接表实现的图 37 | int minDistance[MAXN]; //源点到各点最短距离 38 | int cost[MAXN]; //记录花费 39 | 40 | void Dijkstra(int start) { 41 | minDistance[start] = 0; 42 | cost[start] = 0; 43 | priority_queue myPriorityQueue; 44 | myPriorityQueue.push(Point(start, minDistance[start])); 45 | while (!myPriorityQueue.empty()) { 46 | int u = myPriorityQueue.top().number; //离源点最近的点 47 | myPriorityQueue.pop(); 48 | for (int i = 0; i < graph[u].size(); ++i) { 49 | int v = graph[u][i].to; 50 | int l = graph[u][i].length; 51 | int p = graph[u][i].price; 52 | if ((minDistance[v] == minDistance[u] + l && cost[v] > cost[u] + p) || minDistance[v] > minDistance[u] + l) { 53 | minDistance[v] = minDistance[u] + l; 54 | cost[v] = cost[u] + p; 55 | myPriorityQueue.push(Point(v, minDistance[v])); 56 | } 57 | } 58 | } 59 | return ; 60 | } 61 | 62 | int main() { 63 | int n, m; 64 | while (scanf("%d%d", &n, &m) != EOF) { 65 | if (n == 0 && m == 0) { 66 | break; 67 | } 68 | memset(graph, 0, sizeof(graph)); 69 | fill(minDistance, minDistance + n + 1, INF); 70 | fill(cost, cost + n + 1, INF); 71 | while (m--) { 72 | int from, to, length, price; 73 | scanf("%d%d%d%d", &from, &to, &length, &price); 74 | graph[from].push_back(Edge(to, length, price)); 75 | graph[to].push_back(Edge(from, length, price)); 76 | } 77 | int start, terminal; //起点与终点 78 | scanf("%d%d", &start, &terminal); 79 | Dijkstra(start); 80 | printf("%d %d\n", minDistance[terminal], cost[terminal]); 81 | } 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /Chapter11/11.8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Legal or Not 3 | * 题目来源:HDU 3342 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3342 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const int MAXN = 500 + 10; 16 | 17 | vector graph[MAXN]; 18 | int inDegree[MAXN]; //入度 19 | 20 | bool TopologicalSort(int n) { 21 | queue node; 22 | for (int i = 0; i < n; ++i) { 23 | if (inDegree[i] == 0) { 24 | node.push(i); 25 | } 26 | } 27 | int number = 0; //拓扑序列结点个数 28 | while (!node.empty()) { 29 | int u = node.front(); 30 | node.pop(); 31 | number++; //拓扑序列结点加一 32 | for (int i = 0; i < graph[u].size(); ++i) { 33 | int v = graph[u][i]; 34 | inDegree[v]--; //后继结点入度减一 35 | if (inDegree[v] == 0) { 36 | node.push(v); 37 | } 38 | } 39 | } 40 | return n == number; //判断能否产生拓扑排序 41 | } 42 | 43 | int main() { 44 | int n, m; 45 | while (scanf("%d%d", &n, &m) != EOF) { 46 | if (n == 0 && m == 0) { 47 | break; 48 | } 49 | memset(graph, 0, sizeof(graph)); 50 | memset(inDegree, 0, sizeof(inDegree)); 51 | while (m--) { 52 | int from, to; 53 | scanf("%d%d", &from, &to); 54 | graph[from].push_back(to); 55 | inDegree[to]++; 56 | } 57 | if (TopologicalSort(n)) { 58 | printf("YES\n"); 59 | } else { 60 | printf("NO\n"); 61 | } 62 | } 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /Chapter11/11.9.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:确定比赛名次 3 | * 题目来源:HDU 1285 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | const int MAXN = 500 + 10; 17 | 18 | vector graph[MAXN]; 19 | int inDegree[MAXN]; //入度 20 | 21 | vector TopologicalSort(int n) { 22 | vector topology; //拓扑序列 23 | priority_queue, greater > node; 24 | for (int i = 1; i <= n; ++i) { 25 | if (inDegree[i] == 0) { 26 | node.push(i); 27 | } 28 | } 29 | while (!node.empty()) { 30 | int u = node.top(); 31 | node.pop(); 32 | topology.push_back(u); //加入拓扑序列 33 | for (int i = 0; i < graph[u].size(); ++i) { 34 | int v = graph[u][i]; 35 | inDegree[v]--; //后继结点入度减一 36 | if (inDegree[v] == 0) { 37 | node.push(v); 38 | } 39 | } 40 | } 41 | return topology; 42 | } 43 | 44 | int main() { 45 | int n, m; 46 | while (scanf("%d%d", &n, &m) != EOF) { 47 | memset(graph, 0, sizeof(graph)); 48 | memset(inDegree, 0, sizeof(inDegree)); 49 | while (m--) { 50 | int from, to; 51 | scanf("%d%d", &from, &to); 52 | graph[from].push_back(to); 53 | inDegree[to]++; 54 | } 55 | vector answer = TopologicalSort(n); 56 | for (int i = 0; i < answer.size(); ++i) { 57 | if (i == 0) { 58 | printf("%d", answer[i]); 59 | } else { 60 | printf(" %d", answer[i]); 61 | } 62 | } 63 | printf("\n"); 64 | } 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /Chapter12/12.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:N阶楼梯上楼问题 3 | * 题目来源:华中科技大学复试上机题 4 | * 题目链接:http://t.cn/Aij9Fr3V 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 90 + 10; 14 | 15 | long long dp[MAXN]; 16 | 17 | void Initial() { 18 | for (int i = 0; i < MAXN; ++i) { 19 | if (i == 0 || i == 1) { 20 | dp[i] = 1; 21 | } else { 22 | dp[i] = dp[i - 1] + dp[i - 2]; 23 | } 24 | } 25 | return ; 26 | } 27 | 28 | int main() { 29 | Initial(); 30 | int n; 31 | while (scanf("%d", &n) != EOF) { 32 | printf("%lld\n", dp[n]); 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Chapter12/12.10.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:The Triangle 3 | * 题目来源:POJ 1163 4 | * 题目链接:http://poj.org/problem?id=1163 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 100 + 10; 14 | 15 | int dp[MAXN][MAXN]; 16 | int matrix[MAXN][MAXN]; 17 | 18 | int main() { 19 | int n; 20 | scanf("%d", &n); 21 | for (int i = 0; i < n; ++i) { 22 | for (int j = 0; j <= i; ++j) { 23 | scanf("%d", &matrix[i][j]); 24 | dp[i][j] = matrix[i][j]; 25 | } 26 | } 27 | for (int i = n - 2; i >= 0; --i) { 28 | for (int j = 0; j <= i; ++j) { 29 | dp[i][j] += max(dp[i + 1][j], dp[i + 1][j + 1]); 30 | } 31 | } 32 | printf("%d\n", dp[0][0]); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter12/12.11.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Monkey Banana Problem 3 | * 题目来源:LightOJ 1004 4 | * 题目链接:http://lightoj.com/volume_showproblem.php?problem=1004 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 100 + 10; 14 | 15 | int dp[2 * MAXN][MAXN]; 16 | int matrix[2 * MAXN][MAXN]; 17 | 18 | int main() { 19 | int caseNumber; 20 | scanf("%d", &caseNumber); 21 | for (int current = 1; current <= caseNumber; ++current) { 22 | int n; 23 | scanf("%d", &n); 24 | for (int i = 0; i < n; ++i) { 25 | for (int j = 0; j <= i; ++j) { 26 | scanf("%d", &matrix[i][j]); 27 | dp[i][j] = matrix[i][j]; 28 | } 29 | } 30 | for (int i = n; i < 2 * n - 1; ++i) { 31 | for (int j = 0; j <= 2 * (n - 1) - i; ++j) { 32 | scanf("%d", &matrix[i][j]); 33 | dp[i][j] = matrix[i][j]; 34 | } 35 | } 36 | for (int i = 2 * (n - 1) - 1; i >= n - 1; --i) { 37 | for (int j = 0; j <= 2 * (n - 1) - i; ++j) { 38 | if (j == 0) { //最左端 39 | dp[i][j] += dp[i + 1][j]; 40 | } else if (j == 2 * (n - 1) - i) { //最右端 41 | dp[i][j] += dp[i + 1][j - 1]; 42 | } else { 43 | dp[i][j] += max(dp[i + 1][j], dp[i + 1][j - 1]); 44 | } 45 | } 46 | } 47 | for (int i = n - 2; i >= 0; --i) { 48 | for (int j = 0; j <= i; ++j) { 49 | dp[i][j] += max(dp[i + 1][j], dp[i + 1][j + 1]); 50 | } 51 | } 52 | printf("Case %d: %d\n", current, dp[0][0]); 53 | } 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /Chapter12/12.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:最大序列和 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/AiYSlQMU 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int maxn = 1e6 + 10; 15 | const int INF = INT_MAX; 16 | 17 | long long arr[maxn]; 18 | long long dp[maxn]; 19 | 20 | long long MaxSubsequence(int n) { 21 | long long maximum = -INF; 22 | for (int i = 0; i < n; ++i) { 23 | if (i == 0) { 24 | dp[i] = arr[i]; 25 | } else { 26 | dp[i] = max(arr[i], dp[i - 1] + arr[i]); 27 | } 28 | maximum = max(maximum, dp[i]); 29 | } 30 | return maximum; 31 | } 32 | 33 | int main() { 34 | int n; 35 | while (scanf("%d", &n) != EOF) { 36 | for (int i = 0; i < n; ++i) { 37 | scanf("%lld", &arr[i]); 38 | } 39 | long long answer = MaxSubsequence(n); 40 | printf("%lld\n", answer); 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Chapter12/12.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:最大子矩阵 3 | * 题目来源:北京大学复试上机题 4 | * 题目链接:http://t.cn/AiYSemJz 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int maxn = 100 + 10; 15 | const int INF = INT_MAX; 16 | 17 | int matrix[maxn][maxn]; //原矩阵 18 | int total[maxn][maxn]; //辅助矩阵 19 | int arr[maxn]; //一维数组 20 | int dp[maxn]; 21 | 22 | 23 | int MaxSubsequence(int n) { 24 | int maximum = -INF; 25 | for (int i = 0; i < n; ++i) { 26 | if (i == 0) { 27 | dp[i] = arr[i]; 28 | } else { 29 | dp[i] = max(arr[i], dp[i - 1] + arr[i]); 30 | } 31 | maximum = max(maximum, dp[i]); 32 | } 33 | return maximum; 34 | } 35 | 36 | int MaxSubmatrix(int n) { 37 | int maximal = -INF; 38 | for (int i = 0; i < n; ++i) { 39 | for (int j = i; j < n; ++j) { 40 | for (int k = 0; k < n; ++k) { //获得一维数组 41 | if (i == 0) { 42 | arr[k] = total[j][k]; 43 | } else { 44 | arr[k] = total[j][k] - total[i - 1][k]; 45 | } 46 | } 47 | int current = MaxSubsequence(n); 48 | maximal = max(maximal, current); 49 | } 50 | } 51 | return maximal; 52 | } 53 | 54 | int main() { 55 | int n; 56 | while (scanf("%d", &n) != EOF) { 57 | for (int i = 0; i < n; ++i) { 58 | for (int j = 0; j < n; ++j) { 59 | scanf("%d", &matrix[i][j]); 60 | } 61 | } 62 | for (int i = 0; i < n; ++i) { //初始化辅助函数 63 | for (int j = 0; j < n; ++j) { 64 | if (i == 0) { 65 | total[i][j] = matrix[i][j]; 66 | } else { 67 | total[i][j] = total[i - 1][j] + matrix[i][j]; 68 | } 69 | } 70 | } 71 | int answer = MaxSubmatrix(n); 72 | printf("%d\n", answer); 73 | } 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /Chapter12/12.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:拦截导弹 3 | * 题目来源:北京大学复试上机题 4 | * 题目链接:http://t.cn/AiYCeV3m 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 25 + 10; 14 | 15 | int height[MAXN]; //导弹高度 16 | int dp[MAXN]; 17 | 18 | int main() { 19 | int n; 20 | while (scanf("%d", &n) != EOF) { 21 | for (int i = 0; i < n; ++i) { 22 | scanf("%d", &height[i]); 23 | } 24 | int answer = 0; 25 | for (int i = 0; i < n; ++i) { 26 | dp[i] = 1; //初始化为1 27 | for (int j = 0; j < i; ++j) { 28 | if (height[i] <= height[j]) { 29 | dp[i] = max(dp[i], dp[j] + 1); 30 | } 31 | } 32 | answer = max(answer, dp[i]); //dp数组的最大值 33 | } 34 | printf("%d\n", answer); 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter12/12.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:最大上升子序列和 3 | * 题目来源:北京大学复试上机题 4 | * 题目链接:http://t.cn/AiYNAGD3 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 1000 + 10; 14 | 15 | int arr[MAXN]; 16 | int dp[MAXN]; 17 | 18 | int main() { 19 | int n; 20 | while (scanf("%d", &n) != EOF) { 21 | for (int i = 0; i < n; ++i) { 22 | scanf("%d", &arr[i]); 23 | } 24 | int answer = 0; 25 | for (int i = 0; i < n; ++i) { 26 | dp[i] = arr[i]; //初始化为arr[i] 27 | for (int j = 0; j < i; ++j) { 28 | if (arr[j] < arr[i]) { 29 | dp[i] = max(dp[i], dp[j] + arr[i]); 30 | } 31 | } 32 | answer = max(answer, dp[i]); //dp数组的最大值 33 | } 34 | printf("%d\n", answer); 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter12/12.6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Common Subsequence 3 | * 题目来源:HDU 1159 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 1000 + 10; 15 | 16 | char str1[MAXN]; 17 | char str2[MAXN]; 18 | int dp[MAXN][MAXN]; 19 | 20 | int main() { 21 | while (scanf("%s%s", str1 + 1, str2 +1) != EOF) { //从下标1开始输入 22 | int n = strlen(str1 + 1); 23 | int m = strlen(str2 + 1); 24 | for (int i = 0; i <= n; ++i) { 25 | for (int j = 0; j <= m; ++j) { 26 | if (i == 0 || j == 0) { //边界情况初始化 27 | dp[i][j] = 0; 28 | continue; 29 | } 30 | if (str1[i] == str2[j]) { 31 | dp[i][j] = dp[i - 1][j - 1] + 1; 32 | } else { 33 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 34 | } 35 | } 36 | } 37 | printf("%d\n", dp[n][m]); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /Chapter12/12.7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:点菜问题 3 | * 题目来源:北京大学复试上机题 4 | * 题目链接:http://t.cn/AiYOrkXr 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 100 + 10; 14 | const int MAXM = 1000 + 10; 15 | 16 | int dp[MAXM]; 17 | int value[MAXN]; //物品价值 18 | int weight[MAXN]; //物品重量 19 | 20 | int main() { 21 | int n, m; //n件物品,m容量的背包 22 | while (scanf("%d%d", &m, &n) != EOF) { 23 | for (int i = 0; i < n; ++i) { 24 | scanf("%d%d", &weight[i], &value[i]); 25 | } 26 | for (int i = 0; i <= m; ++i) { 27 | dp[i] = 0; //初始化 28 | } 29 | for (int i = 0; i < n; ++i) { 30 | for (int j = m; j >= weight[i]; --j) { 31 | dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); 32 | } 33 | } 34 | printf("%d\n", dp[m]); 35 | } 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Chapter12/12.8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Piggy-Bank 3 | * 题目来源:HDU 1114 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int INF = INT_MAX / 10; 15 | const int MAXN = 500 + 10; 16 | const int MAXM = 1e4 + 10; 17 | 18 | int dp[MAXM]; 19 | int value[MAXN]; //物品价值 20 | int weight[MAXN]; //物品重量 21 | 22 | int main() { 23 | int caseNumber; 24 | scanf("%d", &caseNumber); 25 | while (caseNumber--) { 26 | int e, f; 27 | scanf("%d%d", &e, &f); 28 | int m = f - e; //背包容量 29 | int n; //物品种类 30 | scanf("%d", &n); 31 | for (int i = 0; i < n; i++) { 32 | scanf("%d%d", &value[i], &weight[i]); 33 | } 34 | for (int i = 1; i <= m; i++) { 35 | dp[i] = INF; //注意初始化 36 | } 37 | dp[0] = 0; 38 | for (int i = 0; i < n; ++i) { 39 | for (int j = weight[i]; j <= m; ++j) { 40 | dp[j] = min(dp[j], dp[j - weight[i]] + value[i]); 41 | } 42 | } 43 | if (dp[m] == INF) { 44 | printf("This is impossible.\n"); 45 | } else { 46 | printf("The minimum amount of money in the piggy-bank is %d.\n", dp[m]); 47 | } 48 | } 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /Chapter12/12.9.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:珍惜现在,感恩生活 3 | * 题目来源:HDU 2191 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 100 + 10; 15 | const int MAXM = 1e4 + 10; 16 | 17 | int dp[MAXM]; 18 | int value[MAXN]; //物品价值 19 | int weight[MAXN]; //物品重量 20 | int amount[MAXN]; //物品数目 21 | int newValue[20 * MAXN]; //拆分后物品价值 22 | int newWeight[20 * MAXN]; //拆分后物品重量 23 | 24 | int main() { 25 | int caseNumber; 26 | scanf("%d", &caseNumber); 27 | while (caseNumber--) { 28 | int n, m; 29 | scanf("%d%d", &m, &n); //n件物品,m容量的背包 30 | int number = 0; //分解后物品数量 31 | for (int i = 0; i < n; ++i) { 32 | scanf("%d%d%d", &weight[i], &value[i], &amount[i]); 33 | for (int j = 1; j <= amount[i]; j <<= 1) { 34 | newValue[number] = j * value[i]; 35 | newWeight[number] = j * weight[i]; 36 | number++; 37 | amount[i] -= j; 38 | } 39 | if (amount[i] > 0) { 40 | newValue[number] = amount[i] * value[i]; 41 | newWeight[number] = amount[i] * weight[i]; 42 | number++; 43 | } 44 | } 45 | for (int i = 0; i <= m; ++i) { 46 | dp[i] = 0; //初始化 47 | } 48 | for (int i = 0; i < number; ++i) { 49 | for (int j = m; j >= newWeight[i]; --j) { 50 | dp[j] = max(dp[j], dp[j - newWeight[i]] + newValue[i]); 51 | } 52 | } 53 | printf("%d\n", dp[m]); 54 | } 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /Chapter2/2.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:abc 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/E9WMRTE 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int main() { 14 | for (int a = 0; a <= 9; ++a) { 15 | for (int b = 0; b <= 9; ++b) { 16 | for (int c = 0; c <= 9; ++c) { 17 | if (a * 100 + b * 110 + c * 12 == 532) { 18 | printf("%d %d %d\n", a, b, c); 19 | } 20 | } 21 | } 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter2/2.10.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:手机键盘 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/E9ulcIc 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int keyTable[26] = {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 1, 2, 3, 4}; 14 | 15 | int main() { 16 | string str; 17 | while (cin >> str) { 18 | int time = 0; 19 | for (int i = 0; i < str.size(); ++i) { 20 | time += keyTable[str[i] - 'a']; //按键时间 21 | if (i != 0 && str[i] - str[i - 1] == keyTable[str[i] - 'a'] - keyTable[str[i - 1] - 'a']) { 22 | time += 2; //等待时间 23 | } 24 | } 25 | printf("%d\n", time); 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Chapter2/2.11.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:XXX定律 3 | * 题目来源:浙江大学复试上机题 4 | * 题目链接:http://t.cn/E937wDs 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int main() { 14 | int n; 15 | while (scanf("%d", &n) != EOF) { 16 | if (n == 0) { 17 | break; 18 | } 19 | int step = 0; 20 | while (n != 1) { 21 | if (n % 2 == 0) { 22 | n = n / 2; 23 | } else { 24 | n = (3 * n + 1) / 2; 25 | } 26 | step++; 27 | } 28 | printf("%d\n", step); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter2/2.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:反序数 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/E9WBrut 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int Reverse(int number) { //求反序数 14 | int reverseNumber = 0; 15 | while (number != 0) { 16 | reverseNumber *= 10; 17 | reverseNumber += number % 10; 18 | number /= 10; 19 | } 20 | return reverseNumber; 21 | } 22 | 23 | int main() { 24 | for (int i = 1000; i <= 9999; ++i) { 25 | if (i * 9 == Reverse(i)) { 26 | printf("%d\n", i); 27 | } 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter2/2.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:对称平方数1 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/E9lUYRn 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int Reverse(int number) { //求反序数 14 | int reverseNumber = 0; 15 | while (number != 0) { 16 | reverseNumber *= 10; 17 | reverseNumber += number % 10; 18 | number /= 10; 19 | } 20 | return reverseNumber; 21 | } 22 | 23 | int main() { 24 | for (int i = 0; i <= 256; ++i) { 25 | if (i * i == Reverse(i * i)) { 26 | printf("%d\n", i); 27 | } 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter2/2.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:输出梯形 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:无 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int main() { 14 | int h; 15 | while (scanf("%d", &h) != EOF) { 16 | int row = h; //行数 17 | int col = h + (h - 1) * 2; //列数 18 | for (int i = 0; i < row; ++i) { 19 | for (int j = 0; j < col; ++j) { 20 | if (j < col - (h + 2 * i)) { //输出空格 21 | printf(" "); 22 | } else { //输出星号 23 | printf("*"); 24 | } 25 | } 26 | printf("\n"); 27 | } 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter2/2.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:叠筐 3 | * 题目来源:HDU 2074 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2074 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 80 + 10; 14 | 15 | char matrix[MAXN][MAXN]; 16 | 17 | int main() { 18 | int n; //叠框大小 19 | char center; //中心花色字符 20 | char outside; //外筐花色字符 21 | bool firstCase = true; //第一组数据标志 22 | while (scanf("%d %c %c", &n, ¢er, &outside) != EOF) { 23 | if (firstCase == true) { 24 | firstCase = false; 25 | } else { 26 | printf("\n"); 27 | } 28 | for (int i = 0; i <= n / 2; ++i) { //(i, i)是每圈左上角坐标 29 | int j = n - i - 1; //(j, j)是每圈右下角坐标 30 | int length = n - 2 * i; //求当前圈的边长 31 | char current; //求当前圈填充字符 32 | if ((n / 2 - i) % 2 == 0) { 33 | current = center; 34 | } else { 35 | current = outside; 36 | } 37 | for (int k = 0; k < length; ++k) { //为当前圈赋值 38 | matrix[i][i + k] = current; //上边赋值 39 | matrix[i + k][i] = current; //左边赋值 40 | matrix[j][j - k] = current; //下边赋值 41 | matrix[j - k][j] = current; //右边赋值 42 | } 43 | } 44 | if (n != 1) { //剔除4个角 45 | matrix[0][0] = ' '; 46 | matrix[0][n - 1] = ' '; 47 | matrix[n - 1][0] = ' '; 48 | matrix[n - 1][n - 1] = ' '; 49 | } 50 | for (int i = 0; i < n; ++i) { //逐行逐列打印 51 | for (int j = 0; j < n; ++j) { 52 | printf("%c", matrix[i][j]); 53 | } 54 | printf("\n"); 55 | } 56 | } 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Chapter2/2.6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:今年的第几天? 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/E9jXK5A 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int dayTable[2][13] = { //预处理 14 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 15 | {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 16 | }; 17 | 18 | bool IsLeapYear(int year) { //判断是否为闰年 19 | return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); 20 | } 21 | 22 | int main() { 23 | int year, month, day; 24 | while (scanf("%d%d%d", &year, &month, &day) != EOF) { 25 | int number = 0; //记录天数 26 | int row = IsLeapYear(year); //判断用哪一行 27 | for (int j = 0; j < month; ++j) { //逐月添加天数 28 | number += dayTable[row][j]; 29 | } 30 | number += day; 31 | printf("%d\n", number); 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter2/2.7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:打印日期 3 | * 题目来源:华中科技大学复试上机题 4 | * 题目链接:http://t.cn/E9YP2a8 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int dayTable[2][13] = { 14 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 15 | {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 16 | }; 17 | 18 | bool IsLeapYear(int year) { 19 | return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); 20 | } 21 | 22 | int main() { 23 | int year, month, day; 24 | int number; //记录天数 25 | while (scanf("%d%d", &year, &number) != EOF) { 26 | month = 0; //初始化月 27 | int row = IsLeapYear(year); 28 | while (number > dayTable[row][month]) { //确定月 29 | number -= dayTable[row][month]; 30 | month++; 31 | } 32 | day = number; //确定日 33 | printf("%04d-%02d-%02d\n", year, month, day); 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Chapter2/2.8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:日期累加 3 | * 题目来源:北京理工大学复试上机题 4 | * 题目链接:http://t.cn/E9Yw0Cr 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int dayTable[2][13] = { 14 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 15 | {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 16 | }; 17 | 18 | bool IsLeapYear(int year) { 19 | return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); 20 | } 21 | 22 | int NumberOfYear(int year) { //返回该年天数 23 | if (IsLeapYear(year)) { 24 | return 366; 25 | } else { 26 | return 365; 27 | } 28 | } 29 | 30 | int main() { 31 | int year, month, day; 32 | int number; 33 | int caseNumber; //组数 34 | scanf("%d", &caseNumber); 35 | while (caseNumber--) { 36 | scanf("%d%d%d%d", &year, &month, &day, &number); 37 | int row = IsLeapYear(year); 38 | for (int j = 0; j < month; ++j) { 39 | number += dayTable[row][j]; 40 | } 41 | number += day; 42 | while (number > NumberOfYear(year)) { //确定年 43 | number -= NumberOfYear(year); 44 | year++; 45 | } 46 | month = 0; 47 | row = IsLeapYear(year); 48 | while (number > dayTable[row][month]) { //确定月 49 | number -= dayTable[row][month]; 50 | month++; 51 | } 52 | day = number; //确定日 53 | printf("%04d-%02d-%02d\n", year, month, day); 54 | } 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /Chapter2/2.9.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:剩下的树 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/E9ufYo5 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 10000 + 10; 14 | 15 | bool tree[MAXN]; 16 | 17 | int main() { 18 | int length; 19 | int caseNumber; 20 | while (scanf("%d%d", &length, &caseNumber) != EOF) { 21 | for (int i = 0; i <= length; ++i) { 22 | tree[i] = true; 23 | } 24 | int number = length + 1; //树的数量 25 | while (caseNumber--) { 26 | int left, right; 27 | scanf("%d%d", &left, &right); 28 | for (int i = left; i <= right; ++i) { 29 | if (tree[i]) { 30 | tree[i] = false; //移除该树 31 | number--; 32 | } 33 | } 34 | } 35 | printf("%d\n", number); 36 | } 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Chapter3/3.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:排序 3 | * 题目来源:华中科技大学复试上机题 4 | * 题目链接:http://t.cn/E9dLx5K 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 100 + 10; 15 | 16 | int arr[MAXN]; 17 | 18 | int main() { 19 | int n; 20 | while (scanf("%d", &n) != EOF) { 21 | for (int i = 0; i < n; ++i) { 22 | scanf("%d", &arr[i]); 23 | } 24 | sort(arr, arr + n); //默认升序排序 25 | for (int i = 0; i < n; ++i) { 26 | printf("%d ", arr[i]); 27 | } 28 | printf("\n"); 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Chapter3/3.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:成绩排序 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/E9d3ysv 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 100 + 10; 15 | 16 | struct Student { 17 | int number; //学号 18 | int score; //成绩 19 | }; 20 | 21 | Student arr[MAXN]; 22 | 23 | bool Compare(Student x, Student y) { //比较函数 24 | if (x.score == y.score) { //成绩相等比较学号 25 | return x.number < y.number; 26 | } else { //成绩不等比较成绩 27 | return x.score < y.score; 28 | } 29 | } 30 | 31 | int main() { 32 | int n; 33 | scanf("%d", &n); 34 | for (int i = 0; i < n; ++i) { 35 | scanf("%d%d", &arr[i].number, &arr[i].score); 36 | } 37 | sort(arr, arr + n, Compare); //按照比较函数排序 38 | for (int i = 0; i < n; ++i) { 39 | printf("%d %d\n", arr[i].number, arr[i].score); 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /Chapter3/3.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:成绩排序 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/E9gyHM1 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 1000 + 10; 15 | 16 | struct Student { 17 | string name; //姓名 18 | int score; //成绩 19 | int order; //次序 20 | }; 21 | 22 | Student arr[MAXN]; 23 | 24 | bool CompareDescending(Student x, Student y) { //降序比较函数 25 | if (x.score == y.score) { //成绩相等比较次序 26 | return x.order < y.order; 27 | } else { //成绩不等比较成绩 28 | return x.score > y.score; 29 | } 30 | } 31 | 32 | bool CompareAscending(Student x, Student y) { //升序比较函数 33 | if (x.score == y.score) { //成绩相等比较次序 34 | return x.order < y.order; 35 | } else { //成绩不等比较成绩 36 | return x.score < y.score; 37 | } 38 | } 39 | 40 | int main() { 41 | int n; 42 | int type; 43 | while (scanf("%d%d", &n, &type) != EOF) { 44 | for (int i = 0; i < n; ++i) { 45 | cin >> arr[i].name >> arr[i].score; 46 | arr[i].order = i; 47 | } 48 | if (type == 0) { //选择比较函数 49 | sort(arr, arr + n, CompareDescending); 50 | } else { 51 | sort(arr, arr + n, CompareAscending); 52 | } 53 | for (int i = 0; i < n; ++i) { 54 | cout << arr[i].name << " " << arr[i].score << endl; 55 | } 56 | } 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Chapter3/3.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:找X 3 | * 题目来源:哈尔滨工业大学复试上机题 4 | * 题目链接:http://t.cn/E9gHFnS 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 200 + 10; 14 | 15 | int arr[MAXN]; 16 | 17 | int main() { 18 | int n; 19 | while (scanf("%d", &n) != EOF) { 20 | for (int i = 0; i < n; ++i) { 21 | scanf("%d", &arr[i]); 22 | } 23 | int x; 24 | scanf("%d", &x); 25 | int answer = -1; 26 | for (int i = 0; i < n; ++i) { 27 | if (arr[i] == x) { 28 | answer = i; 29 | break; 30 | } 31 | } 32 | printf("%d\n", answer); 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Chapter3/3.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:查找 3 | * 题目来源:北京邮电大学复试上机题 4 | * 题目链接:http://t.cn/E9g8aaR 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 100 + 10; 15 | 16 | int arr[MAXN]; 17 | 18 | bool BinarySearch(int n, int target) { 19 | int left = 0; 20 | int right = n - 1; 21 | while (left <= right) { 22 | int middle = left + (right - left) / 2; //中间位置 23 | if (arr[middle] < target) { //小于关键字,舍弃左边 24 | left = middle + 1; 25 | } else if (target < arr[middle]) { //大于关键字,舍弃右边 26 | right = middle - 1; 27 | } else { 28 | return true; //查找成功 29 | } 30 | } 31 | return false; 32 | } 33 | 34 | int main() { 35 | int n, m; 36 | while (scanf("%d", &n) != EOF) { 37 | for (int i = 0; i < n; ++i) { 38 | scanf("%d", &arr[i]); 39 | } 40 | sort(arr, arr + n); //先排序再查找 41 | scanf("%d", &m); 42 | for (int i = 0; i < m; ++i) { 43 | int target; 44 | scanf("%d", &target); 45 | if (BinarySearch(n, target)) { 46 | printf("YES\n"); 47 | } else { 48 | printf("NO\n"); 49 | } 50 | } 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Chapter4/4.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:特殊乘法 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/Ai8by9vW 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | int main() { 15 | string str1, str2; 16 | while (cin >> str1 >> str2) { 17 | int answer = 0; 18 | for (int i = 0; i < str1.size(); ++i) { 19 | for (int j = 0; j < str2.size(); ++j) { 20 | answer += (str1[i] - '0') * (str2[j] - '0'); 21 | } 22 | } 23 | printf("%d\n", answer); 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter4/4.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:密码翻译 3 | * 题目来源:北京大学复试上机题 4 | * 题目链接:http://t.cn/Ai8bGaIx 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | int main() { 15 | string str; 16 | while (getline(cin, str)) { 17 | for (int i = 0; i < str.size(); ++i) { 18 | if (('A' <= str[i] && str[i] <= 'Y') || ('a' <= str[i] && str[i] <= 'y')) { 19 | str[i]++; 20 | } else if (str[i] == 'z' || str[i] == 'Z') { 21 | str[i] -= 25; 22 | } 23 | } 24 | cout << str << endl; 25 | return 0; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chapter4/4.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:简单密码 3 | * 题目来源:北京大学复试上机题 4 | * 题目链接:http://t.cn/Ai8bih2z 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | int main() { 15 | string str; 16 | while (getline(cin, str)) { //起始行 17 | if (str == "ENDOFINPUT") { 18 | break; 19 | } 20 | getline(cin, str); //密文 21 | for (int i = 0; i < str.size(); ++i) { 22 | if ('A' <= str[i] && str[i] <= 'Z') { 23 | str[i] = (str[i] - 'A' - 5 + 26) % 26 + 'A'; 24 | } 25 | } 26 | cout << str << endl; 27 | getline(cin, str); //结束行 28 | return 0; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter4/4.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:统计字符 3 | * 题目来源:浙江大学复试上机题 4 | * 题目链接:http://t.cn/Ai8fvq4I 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const int MAXN = 256; 16 | 17 | int number[MAXN]; 18 | 19 | int main() { 20 | string str1, str2; 21 | while (getline(cin, str1)) { 22 | if (str1 == "#") { 23 | break; 24 | } 25 | getline(cin, str2); 26 | memset(number, 0, sizeof(number)); 27 | for (int i = 0; i < str2.size(); ++i) { 28 | number[str2[i]]++; 29 | } 30 | for (int i = 0; i < str1.size(); ++i) { 31 | printf("%c %d\n", str1[i], number[str1[i]]); 32 | } 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Chapter4/4.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:字母统计 3 | * 题目来源:浙江大学复试上机题 4 | * 题目链接:http://t.cn/Ai8VB72e 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const int MAXN = 26 16 | 17 | int number[MAXN]; 18 | 19 | int main() { 20 | string str; 21 | while (cin >> str) { 22 | memset(number, 0, sizeof(number)); 23 | for (int i = 0; i < str.size(); ++i) { 24 | if ('A' <= str[i] && str[i] <= 'Z') { 25 | number[str[i] - 'A']++; 26 | } 27 | } 28 | for (int i = 0; i < 26; ++i) { 29 | printf("%c:%d\n", 'A' + i, number[i]); 30 | } 31 | } 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter4/4.6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Number Sequence 3 | * 题目来源:HDU 1711 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXM = 10000 + 10; 14 | const int MAXN = 1000000 + 10; 15 | 16 | int nextTable[MAXM]; 17 | int pattern[MAXM]; 18 | int text[MAXN]; 19 | 20 | void GetNextTable(int m) { //创建next表 21 | int j = 0; 22 | nextTable[j] = -1; 23 | int t = nextTable[j]; 24 | while (j < m) { 25 | if (t == -1 || pattern[j] == pattern[t]) { 26 | j++; 27 | t++; 28 | nextTable[j] = t; 29 | } else { 30 | t = nextTable[t]; 31 | } 32 | } 33 | return ; 34 | } 35 | 36 | int KMP(int n, int m) { 37 | GetNextTable(m); 38 | int i = 0; 39 | int j = 0; 40 | while (i < n && j < m) { 41 | if (j == -1 || text[i] == pattern[j]) { //当前字符匹配成功 42 | i++; 43 | j++; 44 | } else { 45 | j = nextTable[j]; //当前字符匹配失败 46 | } 47 | } 48 | if (j == m) { //模式串匹配成功 49 | return i - j + 1; 50 | } else { //模式串匹配失败 51 | return -1; 52 | } 53 | } 54 | 55 | int main() { 56 | int caseNumber; 57 | scanf("%d", &caseNumber); 58 | while (caseNumber--) { 59 | int n, m; 60 | scanf("%d%d", &n, &m); 61 | for (int i = 0; i < n; ++i) { 62 | scanf("%d", &text[i]); 63 | } 64 | for (int j = 0; j < m; ++j) { 65 | scanf("%d", &pattern[j]); 66 | } 67 | printf("%d\n", KMP(n, m)); 68 | } 69 | return 0; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /Chapter4/4.7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Oulipo 3 | * 题目来源:POJ 3461 4 | * 题目链接:http://poj.org/problem?id=3461 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXM = 10000 + 10; 15 | 16 | int nextTable[MAXM]; 17 | 18 | void GetNextTable(string pattern) { //创建next表 19 | int m = pattern.size(); 20 | int j = 0; 21 | nextTable[j] = -1; 22 | int t = nextTable[j]; 23 | while (j < m) { 24 | if (t == -1 || pattern[j] == pattern[t]) { 25 | j++; 26 | t++; 27 | nextTable[j] = t; 28 | } else { 29 | t = nextTable[t]; 30 | } 31 | } 32 | return ; 33 | } 34 | 35 | int KMP(string text, string pattern) { 36 | GetNextTable(pattern); 37 | int n = text.size(); 38 | int m = pattern.size(); 39 | int i = 0; 40 | int j = 0; 41 | int number = 0; //记录匹配次数 42 | while (i < n) { 43 | if (j == -1 || text[i] == pattern[j]) { //当前字符匹配成功 44 | i++; 45 | j++; 46 | } else { 47 | j = nextTable[j]; //当前字符匹配失败 48 | } 49 | if (j == m) { //模式串匹配成功 50 | number++; 51 | j = nextTable[j]; 52 | } 53 | } 54 | return number; 55 | } 56 | 57 | int main() { 58 | int caseNumber; 59 | scanf("%d", &caseNumber); 60 | while (caseNumber--) { 61 | string pattern, text; 62 | cin >> pattern >> text; 63 | printf("%d\n", KMP(text, pattern)); 64 | } 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /Chapter5/5.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:完数VS盈数 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/AiKEyQWW 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | vector perfectNumber; //完数 15 | vector abundantNumber; //盈数 16 | 17 | int DivisorSum(int number) { 18 | int sum = 0; 19 | for (int i = 1; i < number; ++i) { 20 | if (number % i == 0) { 21 | sum += i; 22 | } 23 | } 24 | return sum; 25 | } 26 | 27 | int main() { 28 | for (int i = 2; i <= 60; ++i) { 29 | if (i == DivisorSum(i)) { 30 | perfectNumber.push_back(i); 31 | } else if (i < DivisorSum(i)) { 32 | abundantNumber.push_back(i); 33 | } 34 | } 35 | printf("E:"); 36 | for (int i = 0; i < perfectNumber.size(); ++i) { 37 | printf(" %d", perfectNumber[i]); 38 | } 39 | printf("\n"); 40 | printf("G:"); 41 | for (int i = 0; i < abundantNumber.size(); ++i) { 42 | printf(" %d", abundantNumber[i]); 43 | } 44 | printf("\n"); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Chapter5/5.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:约瑟夫问题No.2 3 | * 题目来源:bailian 3254 4 | * 题目链接:http://bailian.openjudge.cn/practice/3254 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | int main() { 15 | int n, p, m; 16 | while (scanf("%d%d%d", &n, &p, &m)) { 17 | if (n == 0 && p == 0 && m == 0) { 18 | break; 19 | } 20 | queue children; 21 | for (int i = 1; i <= n; ++i) { //依此加入队列 22 | children.push(i); 23 | } 24 | for (int i = 1; i < p; ++i) { //使编号p的小孩在队首 25 | children.push(children.front()); 26 | children.pop(); 27 | } 28 | while (!children.empty()) { 29 | for (int i = 1; i < m; ++i) { //m - 1小孩依此重新入队 30 | children.push(children.front()); 31 | children.pop(); 32 | } 33 | if (children.size() == 1) { //最后一个小孩的输出不同 34 | printf("%d\n", children.front()); 35 | } else { 36 | printf("%d,", children.front()); 37 | } 38 | children.pop(); 39 | } 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /Chapter5/5.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:猫狗收容所 3 | * 题目来源:程序员面试金典 4 | * 题目链接:无 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | struct animal { 15 | int number; //动物编号 16 | int order; //收容次序 17 | animal(int n, int o): number(n), order(o) {} 18 | }; 19 | 20 | queue cats; 21 | queue dogs; 22 | 23 | int main() { 24 | int n; 25 | scanf("%d", &n); 26 | int order = 0; 27 | for (int i = 0; i < n; ++i) { 28 | int event; 29 | scanf("%d", &event); 30 | if (event == 1) { 31 | int number; //动物编号 32 | scanf("%d", &number); 33 | if (0 < number) { 34 | dogs.push(animal(number, order++)); 35 | } else { 36 | cats.push(animal(number, order++)); 37 | } 38 | } else { 39 | int type; //收养方式 40 | scanf("%d", &type); 41 | if (type == 0 && !dogs.empty() && !cats.empty()) { 42 | if (dogs.front().order < cats.front().order) { 43 | printf("%d ", dogs.front().number); 44 | dogs.pop(); 45 | } else { 46 | printf("%d ", cats.front().number); 47 | cats.pop(); 48 | } 49 | } else if (type == 0 && dogs.empty() && !cats.empty()) { 50 | printf("%d ", cats.front().number); 51 | cats.pop(); 52 | } else if (type == 0 && !dogs.empty() && cats.empty()) { 53 | printf("%d ", dogs.front().number); 54 | dogs.pop(); 55 | } else if (type == 1 && !dogs.empty()) { 56 | printf("%d ", dogs.front().number); 57 | dogs.pop(); 58 | } else if (type == -1 && !cats.empty()) { 59 | printf("%d ", cats.front().number); 60 | cats.pop(); 61 | } 62 | } 63 | } 64 | printf("\n"); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /Chapter5/5.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Zero-complexity Transposition 3 | * 题目来源:上海交通大学复试上机题 4 | * 题目链接:http://t.cn/AiKa20bt 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | stack sequence; 15 | 16 | int main() { 17 | int n; 18 | while (scanf("%d", &n) != EOF) { 19 | while (n--) { 20 | long long number; 21 | scanf("%lld", &number); 22 | sequence.push(number); 23 | } 24 | while (!sequence.empty()) { 25 | printf("%lld ", sequence.top()); 26 | sequence.pop(); 27 | } 28 | printf("\n"); 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Chapter5/5.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:扩号匹配问题 3 | * 题目来源:OpenJudge 1978 4 | * 题目链接:http://ccnu.openjudge.cn/practice/1978/ 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | int main() { 16 | string str; 17 | while (cin >> str) { 18 | stack brackets; 19 | string answer(str.size(), ' '); //初始化为输入长度个空格 20 | for (int i = 0; i < str.size(); ++i) { 21 | if (str[i] == '(') { 22 | brackets.push(i); //压入左括号下标 23 | } else if (str[i] == ')') { 24 | if (!brackets.empty()) { 25 | brackets.pop(); 26 | } else { 27 | answer[i] = '?'; //右括号不匹配 28 | } 29 | } 30 | } 31 | while (!brackets.empty()) { 32 | answer[brackets.top()] = '$'; //左括号不匹配 33 | brackets.pop(); 34 | } 35 | cout << str << endl; 36 | cout << answer << endl; 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /Chapter5/5.6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:简单计算器 3 | * 题目来源:浙江大学复试上机题 4 | * 题目链接:http://t.cn/AiKoGS94 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | int Priority(char c) { //优先级顺序 #,$,+-,*/ 17 | if (c == '#') { 18 | return 0; 19 | } else if (c == '$') { 20 | return 1; 21 | } else if (c == '+' || c == '-') { 22 | return 2; 23 | } else { 24 | return 3; 25 | } 26 | } 27 | 28 | double GetNumber(string str, int& index) { //获得下个数字 29 | double number = 0; 30 | while (isdigit(str[index])) { 31 | number = number * 10 + str[index] - '0'; 32 | index++; 33 | } 34 | return number; 35 | } 36 | 37 | double Calculate(double x, double y, char op) { 38 | double result = 0; 39 | if (op == '+') { 40 | result = x + y; 41 | } else if (op == '-') { 42 | result = x - y; 43 | } else if (op == '*') { 44 | result = x * y; 45 | } else if (op == '/') { 46 | result = x / y; 47 | } 48 | return result; 49 | } 50 | 51 | int main() { 52 | string str; 53 | while (getline(cin, str)) { 54 | if (str == "0") { 55 | break; 56 | } 57 | stack operation; //运算符栈 58 | stack number; //运算数栈 59 | str += '$'; //字符串尾部添加$ 60 | operation.push('#'); //运算符栈底添加# 61 | int index = 0; //字符串下标 62 | while (index < str.size()) { 63 | if (str[index] == ' ') { 64 | index++; 65 | } else if (isdigit(str[index])) { 66 | number.push(GetNumber(str, index)); 67 | } else { 68 | if (Priority(operation.top()) < Priority(str[index])) { 69 | operation.push(str[index]); 70 | index++; 71 | } else { 72 | double y = number.top(); 73 | number.pop(); 74 | double x = number.top(); 75 | number.pop(); 76 | number.push(Calculate(x, y, operation.top())); 77 | operation.pop(); 78 | } 79 | } 80 | } 81 | printf("%.2f\n", number.top()); 82 | } 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /Chapter6/6.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:二进制数 3 | * 题目来源:北京邮电大学复试上机题 4 | * 题目链接:http://t.cn/AiCuKTOv 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | int main() { 15 | int n; 16 | while (scanf("%d", &n) != EOF) { 17 | vector binary; 18 | if (n == 0) { 19 | binary.push_back(0); 20 | } else { 21 | while (n != 0) { 22 | binary.push_back(n % 2); 23 | n /= 2; 24 | } 25 | } 26 | for (int i = binary.size() - 1; i >= 0; --i) { //逆序输出 27 | printf("%d", binary[i]); 28 | } 29 | printf("\n"); 30 | } 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Chapter6/6.10.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:人见人爱A^B 3 | * 题目来源:HDU 2035 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2035 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int FastExponentiation(int a, int b, int mod) { 14 | int answer = 1; //初始化为1 15 | while (b != 0) { //不断将b转换为二进制 16 | if (b % 2 == 1) { //若当前位为1,累乘a的2^k次幂 17 | answer *= a; 18 | answer %= mod; //求后三位 19 | } 20 | b /= 2; 21 | a *= a; //a不断平方 22 | a %= mod; 23 | } 24 | return answer; 25 | } 26 | 27 | int main() { 28 | int a, b; 29 | while (scanf("%d%d", &a, &b) != EOF) { 30 | if (a == 0 && b == 0) { 31 | break; 32 | } 33 | printf("%d\n", FastExponentiation(a, b, 1000)); 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Chapter6/6.11.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:计算两个矩阵的乘积 3 | * 题目来源:哈尔滨工业大学复试上机题 4 | * 题目链接:http://t.cn/Aip450PJ 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 100; 14 | 15 | struct Matrix { 16 | int matrix[MAXN][MAXN]; 17 | int row, col; //行与列 18 | Matrix(int r, int c): row(r), col(c) {} //构造函数 19 | }; 20 | 21 | Matrix Multiply(Matrix x, Matrix y) { //矩阵乘法 22 | Matrix answer(x.row, y.col); 23 | for (int i = 0; i < answer.row; ++i) { 24 | for (int j = 0; j < answer.col; ++j) { 25 | answer.matrix[i][j] = 0; 26 | for (int k = 0; k < x.col; ++k) { 27 | answer.matrix[i][j] += x.matrix[i][k] * y.matrix[k][j]; 28 | } 29 | } 30 | } 31 | return answer; 32 | } 33 | 34 | void InputMatrix(Matrix &x) { //矩阵输入 35 | for (int i = 0; i < x.row; ++i) { 36 | for (int j = 0; j < x.col; ++j) { 37 | scanf("%d", &x.matrix[i][j]); 38 | } 39 | } 40 | } 41 | 42 | void OutputMatrix(Matrix x) { //矩阵输出 43 | for (int i = 0; i < x.row; ++i) { 44 | for (int j = 0; j < x.col; ++j) { 45 | printf("%d ", x.matrix[i][j]); 46 | } 47 | printf("\n"); 48 | } 49 | return ; 50 | } 51 | 52 | int main() { 53 | Matrix x(2, 3); 54 | Matrix y(3, 2); 55 | InputMatrix(x); 56 | InputMatrix(y); 57 | Matrix answer = Multiply(x, y); 58 | OutputMatrix(answer); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Chapter6/6.12.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:计算两个矩阵的乘积 3 | * 题目来源:北京邮电大学复试上机题 4 | * 题目链接:http://t.cn/Aip4T3HX 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAXN = 100; 14 | 15 | struct Matrix { 16 | int matrix[MAXN][MAXN]; 17 | int row, col; 18 | Matrix(int r, int c) : row(r), col(c) {} 19 | }; 20 | 21 | Matrix Multiply(Matrix x, Matrix y) { //矩阵乘法 22 | Matrix answer(x.row, y.col); 23 | for (int i = 0; i < answer.row; ++i) { 24 | for (int j = 0; j < answer.col; ++j) { 25 | answer.matrix[i][j] = 0; 26 | for (int k = 0; k < x.col; ++k) { 27 | answer.matrix[i][j] += x.matrix[i][k] * y.matrix[k][j]; 28 | } 29 | } 30 | } 31 | return answer; 32 | } 33 | 34 | Matrix FastExponentiation(Matrix x, int k) { //矩阵快速幂 35 | Matrix answer(x.row, x.col); 36 | for (int i = 0; i < answer.row; ++i) { //初始化为单位矩阵 37 | for (int j = 0; j < answer.col; ++j) { 38 | if (i == j) { 39 | answer.matrix[i][j] = 1; 40 | } else { 41 | answer.matrix[i][j] = 0; 42 | } 43 | } 44 | } 45 | while (k != 0) { 46 | if (k % 2 == 1) { //不断将k转换为二进制 47 | answer = Multiply(answer, x); 48 | } 49 | k /= 2; 50 | x = Multiply(x, x); //x不断平方 51 | } 52 | return answer; 53 | } 54 | 55 | void InputMatrix(Matrix &x) { //矩阵输入 56 | for (int i = 0; i < x.row; ++i) { 57 | for (int j = 0; j < x.col; ++j) { 58 | scanf("%d", &x.matrix[i][j]); 59 | } 60 | } 61 | } 62 | 63 | void OutputMatrix(Matrix x) { //矩阵输出 64 | for (int i = 0; i < x.row; ++i) { 65 | for (int j = 0; j < x.col; ++j) { 66 | if (j == 0) { 67 | printf("%d", x.matrix[i][j]); 68 | } else { 69 | printf(" %d", x.matrix[i][j]); 70 | } 71 | } 72 | printf("\n"); 73 | } 74 | return ; 75 | } 76 | 77 | int main() { 78 | int n, k; 79 | while (scanf("%d%d", &n, &k) != EOF) { 80 | Matrix x(n, n); 81 | InputMatrix(x); 82 | Matrix answer = FastExponentiation(x, k); 83 | OutputMatrix(answer); 84 | } 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /Chapter6/6.13.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:a+b 3 | * 题目来源:华中科技大学复试上机题 4 | * 题目链接:http://t.cn/AipaWiSG 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const int MAXN = 10000; 16 | 17 | struct BigInteger { 18 | int digit[MAXN]; 19 | int length; 20 | BigInteger(); 21 | BigInteger(int x); 22 | BigInteger(string str); 23 | BigInteger(const BigInteger& b); 24 | BigInteger operator=(int x); 25 | BigInteger operator=(string str); 26 | BigInteger operator=(const BigInteger& b); 27 | bool operator<(const BigInteger& b); 28 | bool operator<=(const BigInteger& b); 29 | bool operator==(const BigInteger& b); 30 | BigInteger operator+(const BigInteger& b); 31 | BigInteger operator-(const BigInteger& b); 32 | BigInteger operator*(const BigInteger& b); 33 | BigInteger operator/(const BigInteger& b); 34 | BigInteger operator%(const BigInteger& b); 35 | friend istream& operator>>(istream& in, BigInteger& b); 36 | friend ostream& operator<<(ostream& out, const BigInteger& b); 37 | }; 38 | 39 | istream& operator>>(istream& in, BigInteger& b) { 40 | string str; 41 | in >> str; 42 | b = str; 43 | return in; 44 | } 45 | 46 | ostream& operator<<(ostream& out, const BigInteger& b) { 47 | for (int i = b.length - 1; i >= 0; --i) { 48 | out << b.digit[i]; 49 | } 50 | return out; 51 | } 52 | 53 | BigInteger::BigInteger() { 54 | memset(digit, 0, sizeof(digit)); 55 | length = 0; 56 | } 57 | 58 | BigInteger::BigInteger(int x) { 59 | memset(digit, 0, sizeof(digit)); 60 | length = 0; 61 | if (x == 0) { 62 | digit[length++] = x; 63 | } 64 | while (x != 0) { 65 | digit[length++] = x % 10; 66 | x /= 10; 67 | } 68 | } 69 | 70 | BigInteger::BigInteger(string str) { 71 | memset(digit, 0, sizeof(digit)); 72 | length = str.size(); 73 | for (int i = 0; i < length; ++i) { 74 | digit[i] = str[length - i - 1] - '0'; 75 | } 76 | } 77 | 78 | BigInteger::BigInteger(const BigInteger& b) { 79 | memset(digit, 0, sizeof(digit)); 80 | length = b.length; 81 | for (int i = 0; i < length; ++i) { 82 | digit[i] = b.digit[i]; 83 | } 84 | } 85 | 86 | BigInteger BigInteger::operator=(int x) { 87 | memset(digit, 0, sizeof(digit)); 88 | length = 0; 89 | if (x == 0) { 90 | digit[length++] = x; 91 | } 92 | while (x != 0) { 93 | digit[length++] = x % 10; 94 | x /= 10; 95 | } 96 | return *this; 97 | } 98 | 99 | BigInteger BigInteger::operator=(string str) { 100 | memset(digit, 0, sizeof(digit)); 101 | length = str.size(); 102 | for (int i = 0; i < length; ++i) { 103 | digit[i] = str[length - i - 1] - '0'; 104 | } 105 | return *this; 106 | } 107 | 108 | BigInteger BigInteger::operator=(const BigInteger& b) { 109 | memset(digit, 0, sizeof(digit)); 110 | length = b.length; 111 | for (int i = 0; i < length; ++i) { 112 | digit[i] = b.digit[i]; 113 | } 114 | return *this; 115 | } 116 | 117 | bool BigInteger::operator<(const BigInteger& b) { 118 | if (length < b.length) { 119 | return true; 120 | } else if (b.length < length) { 121 | return false; 122 | } else { 123 | for (int i = length - 1; i >= 0; --i) { 124 | if (digit[i] == b.digit[i]) { 125 | continue; 126 | } else { 127 | return digit[i] < b.digit[i]; 128 | } 129 | } 130 | } 131 | return false; 132 | } 133 | 134 | bool BigInteger::operator<=(const BigInteger& b) { 135 | if (length < b.length) { 136 | return true; 137 | } else if (b.length < length) { 138 | return false; 139 | } else { 140 | for (int i = length - 1; i >= 0; --i) { 141 | if (digit[i] == b.digit[i]) { 142 | continue; 143 | } else { 144 | return digit[i] < b.digit[i]; 145 | } 146 | } 147 | } 148 | return true; 149 | } 150 | 151 | bool BigInteger::operator==(const BigInteger& b) { 152 | if (length != b.length) { 153 | return false; 154 | } else { 155 | for (int i = length - 1; i >= 0; --i) { 156 | if (digit[i] != b.digit[i]) { 157 | return false; 158 | } 159 | } 160 | } 161 | return true; 162 | } 163 | 164 | BigInteger BigInteger::operator+(const BigInteger& b) { 165 | BigInteger answer; 166 | int carry = 0; 167 | for (int i = 0; i < length || i < b.length; ++i) { 168 | int current = carry + digit[i] + b.digit[i]; 169 | carry = current / 10; 170 | answer.digit[answer.length++] = current % 10; 171 | } 172 | if (carry != 0) { 173 | answer.digit[answer.length++] = carry; 174 | } 175 | return answer; 176 | } 177 | 178 | BigInteger BigInteger::operator-(const BigInteger& b) { 179 | BigInteger answer; 180 | int carry = 0; 181 | for (int i = 0; i < length; ++i) { 182 | int current = digit[i] - b.digit[i] - carry; 183 | if (current < 0) { 184 | current += 10; 185 | carry = 1; 186 | } else { 187 | carry = 0; 188 | } 189 | answer.digit[answer.length++] = current; 190 | } 191 | while (answer.digit[answer.length - 1] == 0 && answer.length > 1) { 192 | answer.length--; 193 | } 194 | return answer; 195 | 196 | } 197 | 198 | BigInteger BigInteger::operator*(const BigInteger& b) { 199 | BigInteger answer; 200 | answer.length = length + b.length; 201 | for (int i = 0; i < length; ++i) { 202 | for (int j = 0; j < b.length; ++j) { 203 | answer.digit[i + j] += digit[i] * b.digit[j]; 204 | } 205 | } 206 | for (int i = 0; i < answer.length; ++i) { 207 | answer.digit[i + 1] += answer.digit[i] / 10; 208 | answer.digit[i] %= 10; 209 | } 210 | while (answer.digit[answer.length - 1] == 0 && answer.length > 1) { 211 | answer.length--; 212 | } 213 | return answer; 214 | } 215 | 216 | BigInteger BigInteger::operator/(const BigInteger& b) { 217 | BigInteger answer; 218 | answer.length = length; 219 | BigInteger remainder = 0; 220 | BigInteger temp = b; 221 | for (int i = length - 1; i >= 0; --i) { 222 | if (!(remainder.length == 1 && remainder.digit[0] == 0)) { 223 | for (int j = remainder.length - 1; j >= 0; --j) { 224 | remainder.digit[j + 1] = remainder.digit[j]; 225 | } 226 | remainder.length++; 227 | } 228 | remainder.digit[0] = digit[i]; 229 | while (temp <= remainder) { 230 | remainder = remainder - temp; 231 | answer.digit[i]++; 232 | } 233 | } 234 | while (answer.digit[answer.length - 1] == 0 && answer.length > 1) { 235 | answer.length--; 236 | } 237 | return answer; 238 | } 239 | 240 | BigInteger BigInteger::operator%(const BigInteger& b) { 241 | BigInteger remainder = 0; 242 | BigInteger temp = b; 243 | for (int i = length - 1; i >= 0; --i) { 244 | if (!(remainder.length == 1 && remainder.digit[0] == 0)) { 245 | for (int j = remainder.length - 1; j >= 0; --j) { 246 | remainder.digit[j + 1] = remainder.digit[j]; 247 | } 248 | remainder.length++; 249 | } 250 | remainder.digit[0] = digit[i]; 251 | while (temp <= remainder) { 252 | remainder = remainder - temp; 253 | } 254 | } 255 | return remainder; 256 | } 257 | 258 | int main() { 259 | BigInteger a; 260 | BigInteger b; 261 | while (cin >> a >> b) { 262 | cout << a + b << endl; 263 | } 264 | return 0; 265 | } 266 | -------------------------------------------------------------------------------- /Chapter6/6.14.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:N的阶乘 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/AipaBKQJ 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const int MAXN = 10000; 16 | 17 | struct BigInteger { 18 | int digit[MAXN]; 19 | int length; 20 | BigInteger(); 21 | BigInteger(int x); 22 | BigInteger(string str); 23 | BigInteger(const BigInteger& b); 24 | BigInteger operator=(int x); 25 | BigInteger operator=(string str); 26 | BigInteger operator=(const BigInteger& b); 27 | bool operator<(const BigInteger& b); 28 | bool operator<=(const BigInteger& b); 29 | bool operator==(const BigInteger& b); 30 | BigInteger operator+(const BigInteger& b); 31 | BigInteger operator-(const BigInteger& b); 32 | BigInteger operator*(const BigInteger& b); 33 | BigInteger operator/(const BigInteger& b); 34 | BigInteger operator%(const BigInteger& b); 35 | friend istream& operator>>(istream& in, BigInteger& b); 36 | friend ostream& operator<<(ostream& out, const BigInteger& b); 37 | }; 38 | 39 | istream& operator>>(istream& in, BigInteger& b) { 40 | string str; 41 | in >> str; 42 | b = str; 43 | return in; 44 | } 45 | 46 | ostream& operator<<(ostream& out, const BigInteger& b) { 47 | for (int i = b.length - 1; i >= 0; --i) { 48 | out << b.digit[i]; 49 | } 50 | return out; 51 | } 52 | 53 | BigInteger::BigInteger() { 54 | memset(digit, 0, sizeof(digit)); 55 | length = 0; 56 | } 57 | 58 | BigInteger::BigInteger(int x) { 59 | memset(digit, 0, sizeof(digit)); 60 | length = 0; 61 | if (x == 0) { 62 | digit[length++] = x; 63 | } 64 | while (x != 0) { 65 | digit[length++] = x % 10; 66 | x /= 10; 67 | } 68 | } 69 | 70 | BigInteger::BigInteger(string str) { 71 | memset(digit, 0, sizeof(digit)); 72 | length = str.size(); 73 | for (int i = 0; i < length; ++i) { 74 | digit[i] = str[length - i - 1] - '0'; 75 | } 76 | } 77 | 78 | BigInteger::BigInteger(const BigInteger& b) { 79 | memset(digit, 0, sizeof(digit)); 80 | length = b.length; 81 | for (int i = 0; i < length; ++i) { 82 | digit[i] = b.digit[i]; 83 | } 84 | } 85 | 86 | BigInteger BigInteger::operator=(int x) { 87 | memset(digit, 0, sizeof(digit)); 88 | length = 0; 89 | if (x == 0) { 90 | digit[length++] = x; 91 | } 92 | while (x != 0) { 93 | digit[length++] = x % 10; 94 | x /= 10; 95 | } 96 | return *this; 97 | } 98 | 99 | BigInteger BigInteger::operator=(string str) { 100 | memset(digit, 0, sizeof(digit)); 101 | length = str.size(); 102 | for (int i = 0; i < length; ++i) { 103 | digit[i] = str[length - i - 1] - '0'; 104 | } 105 | return *this; 106 | } 107 | 108 | BigInteger BigInteger::operator=(const BigInteger& b) { 109 | memset(digit, 0, sizeof(digit)); 110 | length = b.length; 111 | for (int i = 0; i < length; ++i) { 112 | digit[i] = b.digit[i]; 113 | } 114 | return *this; 115 | } 116 | 117 | bool BigInteger::operator<(const BigInteger& b) { 118 | if (length < b.length) { 119 | return true; 120 | } else if (b.length < length) { 121 | return false; 122 | } else { 123 | for (int i = length - 1; i >= 0; --i) { 124 | if (digit[i] == b.digit[i]) { 125 | continue; 126 | } else { 127 | return digit[i] < b.digit[i]; 128 | } 129 | } 130 | } 131 | return false; 132 | } 133 | 134 | bool BigInteger::operator<=(const BigInteger& b) { 135 | if (length < b.length) { 136 | return true; 137 | } else if (b.length < length) { 138 | return false; 139 | } else { 140 | for (int i = length - 1; i >= 0; --i) { 141 | if (digit[i] == b.digit[i]) { 142 | continue; 143 | } else { 144 | return digit[i] < b.digit[i]; 145 | } 146 | } 147 | } 148 | return true; 149 | } 150 | 151 | bool BigInteger::operator==(const BigInteger& b) { 152 | if (length != b.length) { 153 | return false; 154 | } else { 155 | for (int i = length - 1; i >= 0; --i) { 156 | if (digit[i] != b.digit[i]) { 157 | return false; 158 | } 159 | } 160 | } 161 | return true; 162 | } 163 | 164 | BigInteger BigInteger::operator+(const BigInteger& b) { 165 | BigInteger answer; 166 | int carry = 0; 167 | for (int i = 0; i < length || i < b.length; ++i) { 168 | int current = carry + digit[i] + b.digit[i]; 169 | carry = current / 10; 170 | answer.digit[answer.length++] = current % 10; 171 | } 172 | if (carry != 0) { 173 | answer.digit[answer.length++] = carry; 174 | } 175 | return answer; 176 | } 177 | 178 | BigInteger BigInteger::operator-(const BigInteger& b) { 179 | BigInteger answer; 180 | int carry = 0; 181 | for (int i = 0; i < length; ++i) { 182 | int current = digit[i] - b.digit[i] - carry; 183 | if (current < 0) { 184 | current += 10; 185 | carry = 1; 186 | } else { 187 | carry = 0; 188 | } 189 | answer.digit[answer.length++] = current; 190 | } 191 | while (answer.digit[answer.length - 1] == 0 && answer.length > 1) { 192 | answer.length--; 193 | } 194 | return answer; 195 | 196 | } 197 | 198 | BigInteger BigInteger::operator*(const BigInteger& b) { 199 | BigInteger answer; 200 | answer.length = length + b.length; 201 | for (int i = 0; i < length; ++i) { 202 | for (int j = 0; j < b.length; ++j) { 203 | answer.digit[i + j] += digit[i] * b.digit[j]; 204 | } 205 | } 206 | for (int i = 0; i < answer.length; ++i) { 207 | answer.digit[i + 1] += answer.digit[i] / 10; 208 | answer.digit[i] %= 10; 209 | } 210 | while (answer.digit[answer.length - 1] == 0 && answer.length > 1) { 211 | answer.length--; 212 | } 213 | return answer; 214 | } 215 | 216 | BigInteger BigInteger::operator/(const BigInteger& b) { 217 | BigInteger answer; 218 | answer.length = length; 219 | BigInteger remainder = 0; 220 | BigInteger temp = b; 221 | for (int i = length - 1; i >= 0; --i) { 222 | if (!(remainder.length == 1 && remainder.digit[0] == 0)) { 223 | for (int j = remainder.length - 1; j >= 0; --j) { 224 | remainder.digit[j + 1] = remainder.digit[j]; 225 | } 226 | remainder.length++; 227 | } 228 | remainder.digit[0] = digit[i]; 229 | while (temp <= remainder) { 230 | remainder = remainder - temp; 231 | answer.digit[i]++; 232 | } 233 | } 234 | while (answer.digit[answer.length - 1] == 0 && answer.length > 1) { 235 | answer.length--; 236 | } 237 | return answer; 238 | } 239 | 240 | BigInteger BigInteger::operator%(const BigInteger& b) { 241 | BigInteger remainder = 0; 242 | BigInteger temp = b; 243 | for (int i = length - 1; i >= 0; --i) { 244 | if (!(remainder.length == 1 && remainder.digit[0] == 0)) { 245 | for (int j = remainder.length - 1; j >= 0; --j) { 246 | remainder.digit[j + 1] = remainder.digit[j]; 247 | } 248 | remainder.length++; 249 | } 250 | remainder.digit[0] = digit[i]; 251 | while (temp <= remainder) { 252 | remainder = remainder - temp; 253 | } 254 | } 255 | return remainder; 256 | } 257 | 258 | int main() { 259 | int n; 260 | while (cin >> n) { 261 | BigInteger answer(1); 262 | for (int i = 1; i <= n; ++i) { 263 | answer = answer * BigInteger(i); 264 | } 265 | cout << answer << endl; 266 | } 267 | return 0; 268 | } 269 | -------------------------------------------------------------------------------- /Chapter6/6.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:进制转换 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/AiCuoPRO 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | string Divide(string str, int x) { //字符串除法 16 | int remainder = 0; //保存余数 17 | for (int i = 0; i < str.size(); ++i) { 18 | int current = remainder * 10 + str[i] - '0'; 19 | str[i] = current / x + '0'; 20 | remainder = current % x; 21 | } 22 | int position = 0; 23 | while (str[position] == '0') { //寻找首个非0下标 24 | position++; 25 | } 26 | return str.substr(position); //删除前置多余的0 27 | } 28 | 29 | int main() { 30 | string str; 31 | while (cin >> str) { 32 | vector binary; 33 | while (str.size() != 0) { 34 | int last = str[str.size() - 1] - '0'; //最低位的值 35 | binary.push_back(last % 2); //取模运算 36 | str = Divide(str, 2); //整除运算 37 | } 38 | for (int i = binary.size() - 1; i >= 0; --i) { 39 | printf("%d", binary[i]); 40 | } 41 | printf("\n"); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /Chapter6/6.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:10进制 VS 2进制 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/AiCuoHKg 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | string Divide(string str, int x) { //字符串除法 16 | int remainder = 0; //保存余数 17 | for (int i = 0; i < str.size(); ++i) { 18 | int current = remainder * 10 + str[i] - '0'; 19 | str[i] = current / x + '0'; 20 | remainder = current % x; 21 | } 22 | int position = 0; 23 | while (str[position] == '0') { //寻找首个非0下标 24 | position++; 25 | } 26 | return str.substr(position); //删除前置多余的0 27 | } 28 | 29 | string Multiple(string str, int x) { //字符串乘法 30 | int carry = 0; //保存进位 31 | for (int i = str.size() - 1; i >= 0; --i) { 32 | int current = x * (str[i] - '0') + carry; 33 | str[i] = current % 10 + '0'; 34 | carry = current / 10; 35 | } 36 | if (carry != 0) { //仍有进位 37 | str = to_string(carry) + str; 38 | } 39 | return str; 40 | } 41 | 42 | string Add(string str, int x) { //字符串加法 43 | int carry = x; 44 | for (int i = str.size() - 1; i >= 0; --i) { 45 | int current = (str[i] - '0') + carry; 46 | str[i] = current % 10 + '0'; 47 | carry = current / 10; 48 | } 49 | if (carry != 0) { //仍有进位 50 | str = to_string(carry) + str; 51 | } 52 | return str; 53 | } 54 | 55 | int main() { 56 | string str; 57 | while (cin >> str) { 58 | vector binary; 59 | while (str.size() != 0) { 60 | int last = str[str.size() - 1] - '0'; //最低位的值 61 | binary.push_back(last % 2); 62 | str = Divide(str, 2); //字符串除2 63 | } 64 | string answer = "0"; 65 | for (int i = 0; i < binary.size(); ++i) { 66 | answer = Multiple(answer, 2); //字符串乘2 67 | answer = Add(answer, binary[i]); //加数位值 68 | } 69 | cout << answer << endl; 70 | } 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /Chapter6/6.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:进制转换2 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/AiCuKG7E 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | char IntToChar(int x) { //数字变成字符 16 | if (x < 10) { 17 | return x + '0'; 18 | } else { 19 | return x - 10 + 'a'; 20 | } 21 | } 22 | 23 | int CharToInt(char c) { //字符变成数字 24 | if (c >= '0' && c <= '9') { 25 | return c - '0'; 26 | } else { 27 | return c - 'A' + 10; 28 | } 29 | } 30 | 31 | int main() { 32 | int m, n; 33 | scanf("%d%d", &m, &n); 34 | string str; 35 | cin >> str; 36 | long long number = 0; 37 | for (int i = 0; i < str.size(); ++i) { //从m进制变成十进制 38 | number *= m; 39 | number += CharToInt(str[i]); 40 | } 41 | vector answer; 42 | if (number == 0) { 43 | answer.push_back('0'); 44 | } else { 45 | while (number != 0) { //从十进制变成n进制 46 | answer.push_back(IntToChar(number % n)); 47 | number /= n; 48 | } 49 | } 50 | for (int i = answer.size() - 1; i >= 0; --i) { //逆序输出 51 | printf("%c", answer[i]); 52 | } 53 | printf("\n"); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /Chapter6/6.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:最大公约数 3 | * 题目来源:哈尔滨工业大学复试上机题 4 | * 题目链接:http://t.cn/AiCuWLTS 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int GCD(int a, int b) { 14 | if (b == 0) { 15 | return a; 16 | } else { 17 | return GCD(b, a % b); 18 | } 19 | } 20 | 21 | int main() { 22 | int a, b; 23 | while (scanf("%d%d", &a, &b) != EOF) { 24 | printf("%d\n", GCD(a, b)); 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter6/6.6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:最小公倍数 3 | * 题目来源:HDU 1108 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1108 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int GCD(int a, int b) { 14 | if (b == 0) { 15 | return a; 16 | } else { 17 | return GCD(b, a % b); 18 | } 19 | } 20 | 21 | int main() { 22 | int a, b; 23 | while (scanf("%d%d", &a, &b) != EOF) { 24 | printf("%d\n", a * b / GCD(a, b)); 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter6/6.7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:素数判断 3 | * 题目来源:哈尔滨工业大学复试上机题 4 | * 题目链接:http://t.cn/AiCuWE0Q 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | bool Judge(int x) { //判断是否为质数 15 | if (x < 2) { //小于2必定不是 16 | return false; 17 | } 18 | int bound = sqrt(x); //确定判断上界 19 | for (int i = 2; i <= bound; ++i) { 20 | if (x % i == 0) { 21 | return false; 22 | } 23 | } 24 | return true; 25 | } 26 | 27 | int main() { 28 | int n; 29 | while (scanf("%d", &n) != EOF) { 30 | if (Judge(n)) { 31 | printf("yes\n"); 32 | } else { 33 | printf("no\n"); 34 | } 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter6/6.8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:素数 3 | * 题目来源:北京航天航空大学复试上机题 4 | * 题目链接:http://t.cn/AiCulqtW 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 10000 + 10; 15 | 16 | vector prime; //保存质数 17 | bool isPrime[MAXN]; //标记数组 18 | 19 | void Initial() { 20 | for (int i = 0; i < MAXN; ++i) { //初始化 21 | isPrime[i] = true; 22 | } 23 | isPrime[0] = false; 24 | isPrime[1] = false; 25 | for (int i = 2; i < MAXN; ++i) { 26 | if (!isPrime[i]) { //非质数则跳过 27 | continue; 28 | } 29 | prime.push_back(i); 30 | if (i > MAXN / i) { //过大的数提前跳出 31 | continue; 32 | } 33 | for (int j = i * i; j < MAXN; j += i) { 34 | isPrime[j] = false; //质数的倍数为非质数 35 | } 36 | } 37 | return ; 38 | } 39 | 40 | int main() { 41 | Initial(); 42 | int n; 43 | while (scanf("%d", &n) != EOF) { 44 | bool isOutput = false; //判断是否有输出 45 | for (int i = 0; i < prime.size() && prime[i] < n; ++i) { 46 | if (prime[i] % 10 == 1) { 47 | isOutput = true; 48 | printf("%d ", prime[i]); 49 | } 50 | } 51 | if (!isOutput) { 52 | printf("-1"); 53 | } 54 | printf("\n"); 55 | } 56 | return 0; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /Chapter6/6.9.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:质因子的个数 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/Aip7J0Oo 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const int MAXN = 4e4; 16 | 17 | vector prime; //保存质数 18 | bool isPrime[MAXN]; //标记数组 19 | 20 | void Initial() { 21 | for (int i = 0; i < MAXN; ++i) { //初始化 22 | isPrime[i] = true; 23 | } 24 | isPrime[0] = false; 25 | isPrime[1] = false; 26 | for (int i = 2; i < MAXN; ++i) { 27 | if (!isPrime[i]) { //非质数则跳过 28 | continue; 29 | } 30 | prime.push_back(i); 31 | if (i > MAXN / i) { //过大的数提前跳出 32 | continue; 33 | } 34 | for (int j = i * i; j < MAXN; j += i) { 35 | isPrime[j] = false; //质数的倍数为非质数 36 | } 37 | } 38 | return ; 39 | } 40 | 41 | int main() { 42 | Initial(); 43 | int n; 44 | while (scanf("%d", &n) != EOF) { 45 | int answer = 0; 46 | for (int i = 0; i < prime.size() && prime[i] < n; ++i) { 47 | int factor = prime[i]; 48 | while (n % factor == 0) { //不断试除 49 | n /= factor; 50 | answer++; 51 | } 52 | } 53 | if (n > 1) { //还存在一个质因数 54 | answer++; 55 | } 56 | printf("%d\n", answer); 57 | } 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Chapter7/7.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:鸡兔同笼 3 | * 题目来源:北京大学复试上机题 4 | * 题目链接:http://t.cn/E9ewERU 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int main() { 14 | int a; 15 | while (scanf("%d", &a) != EOF) { 16 | int minimum = 0; 17 | int maxmum = 0; 18 | if (a % 2 == 0) { //偶数才有解 19 | minimum = a / 4 + (a % 4) / 2; 20 | maxmum = a / 2; 21 | } 22 | printf("%d %d\n", minimum, maxmum); 23 | } 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter7/7.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:FatMouse' Trade 3 | * 题目来源:HDU 1009 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1009 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 1000 + 10; 15 | 16 | struct JavaBean { 17 | double weight; 18 | double cost; 19 | }; 20 | 21 | JavaBean arr[MAXN]; 22 | 23 | bool Compare(JavaBean x, JavaBean y) { 24 | return (x.weight / x.cost) > (y.weight / y.cost); 25 | } 26 | 27 | int main() { 28 | int m, n; 29 | while (scanf("%d%d", &m, &n) != EOF) { 30 | if (m == -1 && n == -1) { 31 | break; 32 | } 33 | for (int i = 0; i < n; ++i) { 34 | scanf("%lf%lf", &arr[i].weight, &arr[i].cost); 35 | } 36 | sort(arr, arr + n, Compare); //性价比降序排列 37 | double answer = 0; 38 | for (int i = 0; i < n; ++i) { 39 | if (m >= arr[i].cost) { //全部买下 40 | answer += arr[i].weight; 41 | m -= arr[i].cost; 42 | } else { //只能买部分 43 | answer += arr[i].weight * (m / arr[i].cost); 44 | m = 0; 45 | break; 46 | } 47 | } 48 | printf("%.3f\n", answer); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /Chapter7/7.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Senior's Gun 3 | * 题目来源:HDU 5281 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5281 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 1e5 + 10; 15 | 16 | long long gun[MAXN]; 17 | long long monster[MAXN]; 18 | 19 | bool Compare(long long x, long long y) { 20 | return x > y; 21 | } 22 | 23 | int main() { 24 | int caseNumber; 25 | scanf("%d", &caseNumber); 26 | while (caseNumber--) { 27 | int n, m; 28 | scanf("%d%d", &n, &m); 29 | for (int i = 0; i < n; ++i) { 30 | scanf("%lld", &gun[i]); 31 | } 32 | for (int i = 0; i < m; ++i) { 33 | scanf("%lld", &monster[i]); 34 | } 35 | sort(gun, gun + n, Compare); //枪从大到小排序 36 | sort(monster, monster + m); //怪从小到大排序 37 | long long answer = 0; 38 | for (int i = 0; i < n; ++i) { 39 | if (i >= m || gun[i] <= monster[i]) { 40 | break; 41 | } 42 | answer += (gun[i] - monster[i]); 43 | } 44 | printf("%lld\n", answer); 45 | } 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /Chapter7/7.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:今年暑假不AC 3 | * 题目来源:HDU 2037 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2037 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | const int MAXN = 100 + 10; 15 | 16 | struct Program { 17 | int startTime; 18 | int endTime ; 19 | }; 20 | 21 | Program arr[MAXN]; 22 | 23 | bool Compare(Program x, Program y) { 24 | return x.endTime < y.endTime; 25 | } 26 | 27 | int main() { 28 | int n; 29 | while (scanf("%d", &n) != EOF) { 30 | if (n == 0) { 31 | break; 32 | } 33 | for (int i = 0; i < n; ++i) { 34 | scanf("%d%d", &arr[i].startTime, &arr[i].endTime); 35 | } 36 | sort(arr, arr + n, Compare); //按结束时间升序排序 37 | int currentTime = 0; //设置当前时间 38 | int answer = 0; 39 | for (int i = 0; i < n; ++i) { 40 | if (currentTime <= arr[i].startTime) { //选择看这个节目 41 | currentTime = arr[i].endTime; 42 | answer++; 43 | } 44 | } 45 | printf("%d\n", answer); 46 | } 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Chapter7/7.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Case of Fugitive 3 | * 题目来源:codeforces 555B 4 | * 题目链接:http://codeforces.com/problemset/problem/555/B 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | const int MAXN = 2e5 + 10; 17 | 18 | struct Island { 19 | long long left; //岛屿左端点 20 | long long right; //岛屿右端点 21 | }; 22 | 23 | struct Bridge { 24 | long long length; //桥的长度 25 | long long index; //桥的编号 26 | }; 27 | 28 | struct Interval { 29 | long long minimum; //区间最小值 30 | long long maxmum; //区间最大值 31 | long long index; //区间编号 32 | bool operator< (Interval x) const { 33 | return maxmum > x.maxmum; 34 | } 35 | }; 36 | 37 | Island island[MAXN]; 38 | Bridge bridge[MAXN]; 39 | Interval interval[MAXN]; 40 | long long answer[MAXN]; 41 | 42 | bool IntervalCompare(Interval x, Interval y) { 43 | if (x.minimum == y.minimum) { 44 | return x.maxmum < y.maxmum; 45 | } else { 46 | return x.minimum < y.minimum; 47 | } 48 | } 49 | 50 | bool BridgeCompare(Bridge x, Bridge y) { 51 | return x.length < y.length; 52 | } 53 | 54 | bool Solve(int n, int m) { 55 | priority_queue myQueue; 56 | int position = 0; //当前区间下标 57 | int number = 0; //搭建桥的数目 58 | for (int i = 0; i < m; ++i) { 59 | while (!myQueue.empty() && myQueue.top().maxmum < bridge[i].length) { 60 | myQueue.pop(); //当前区间无法搭建 61 | } 62 | while (position < n && interval[position].minimum <= bridge[i].length && interval[position].maxmum >= bridge[i].length) { 63 | myQueue.push(interval[position]); 64 | position++; 65 | } 66 | if (!myQueue.empty()) { 67 | Interval current = myQueue.top(); 68 | myQueue.pop(); 69 | answer[current.index] = bridge[i].index; 70 | number++; 71 | } 72 | } 73 | return number == n - 1; //判断桥数与区间数是否相等 74 | } 75 | 76 | int main() { 77 | int n, m; 78 | while (scanf("%d%d", &n, &m) != EOF) { 79 | memset(island, 0, sizeof(island)); 80 | memset(bridge, 0, sizeof(bridge)); 81 | memset(interval, 0, sizeof(interval)); 82 | memset(answer, 0, sizeof(answer)); 83 | for (int i = 0; i < n; ++i) { 84 | scanf("%lld%lld", &island[i].left, &island[i].right); 85 | } 86 | for (int i = 0; i < m; ++i) { 87 | scanf("%lld", &bridge[i].length); 88 | bridge[i].index = i + 1; 89 | } 90 | for (int i = 0; i < n - 1; ++i) { 91 | interval[i].minimum = island[i + 1].left - island[i].right; 92 | interval[i].maxmum = island[i + 1].right - island[i].left; 93 | interval[i].index = i; 94 | } 95 | sort(interval, interval + n - 1, IntervalCompare); 96 | sort(bridge, bridge + m, BridgeCompare); 97 | if (Solve(n, m)) { 98 | printf("Yes\n"); 99 | for (int i = 0; i < n - 1; ++i) { 100 | if (i == 0) { 101 | printf("%lld", answer[i]); 102 | } else { 103 | printf(" %lld", answer[i]); 104 | } 105 | } 106 | printf("\n"); 107 | } else { 108 | printf("No\n"); 109 | } 110 | } 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /Chapter8/8.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:n的阶乘 3 | * 题目来源:清华大学复试上机题 4 | * 题目链接:http://t.cn/Ai0ocOUY 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | long long Factorial(int n) { //递归函数 14 | if (n == 0) { //递归出口 15 | return 1; 16 | } else { //递归调用 17 | return n * Factorial(n - 1); 18 | } 19 | } 20 | 21 | int main() { 22 | int n; 23 | while (scanf("%d", &n) != EOF) { 24 | printf("%lld\n", Factorial(n)); 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter8/8.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:汉诺塔III 3 | * 题目来源:HDU2064 4 | * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2064 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | long long Function(int n) { //递归函数 14 | if (n == 1) { //递归出口 15 | return 2; 16 | } else { //递归调用 17 | return 3 * Function(n - 1) + 2; 18 | } 19 | } 20 | 21 | int main() { 22 | int n; 23 | while (scanf("%d", &n) != EOF) { 24 | printf("%lld\n", Function(n)); 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter8/8.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Fibonacci 3 | * 题目来源:上海交通大学复试上机题 4 | * 题目链接:http://t.cn/Ai0K3tU5 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int Fibonacci(int n) { 14 | if (n == 1 || n == 0) { //递归出口 15 | return n; 16 | } else { //递归调用 17 | return Fibonacci(n - 1) + Fibonacci(n - 2); 18 | } 19 | } 20 | 21 | int main() { 22 | int n; 23 | while (scanf("%d", &n) != EOF) { 24 | printf("%d\n", Fibonacci(n)); 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter8/8.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:二叉树 3 | * 题目来源:北京大学复试上机题 4 | * 题目链接:http://t.cn/Ai0Ke6I0 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int CountNodes(int m, int n) { 14 | if (m > n) { //递归出口 15 | return 0; 16 | } else { //递归调用 17 | return 1 + CountNodes(m * 2, n) + CountNodes(m * 2 + 1, n); 18 | } 19 | } 20 | 21 | int main() { 22 | int m, n; 23 | while (scanf("%d%d", &m, &n) != EOF) { 24 | printf("%d\n", CountNodes(m, n)); 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter9/9.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Catch That Cow 3 | * 题目来源:POJ 3278 4 | * 题目链接:http://poj.org/problem?id=3278 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const int MAXN = 1e5 + 10; 16 | 17 | bool visit[MAXN]; 18 | 19 | struct Status { 20 | int position; 21 | int time; 22 | Status(int p, int t): position(p), time(t) {} 23 | }; 24 | 25 | int BFS(int n, int k) { 26 | queue myQueue; 27 | myQueue.push(Status(n, 0)); //压入初始状态 28 | visit[n] = true; //起点已访问 29 | int answer = 0; 30 | while (!myQueue.empty()) { 31 | Status current = myQueue.front(); 32 | myQueue.pop(); 33 | if (current.position == k) { //查找成功 34 | answer = current.time; 35 | } 36 | for (int i = 0; i < 3; ++i) { //转入不同状态 37 | Status next = current; 38 | if (i == 0) { 39 | next.position += 1; 40 | } else if (i == 1) { 41 | next.position -= 1; 42 | } else { 43 | next.position *= 2; 44 | } 45 | if (next.position < 0 || next.position >= MAXN || visit[next.position]) { 46 | continue; //新状态不合法 47 | } 48 | next.time++; 49 | myQueue.push(next); //压入新的状态 50 | visit[next.position] = true; //该点已访问 51 | } 52 | } 53 | return answer; 54 | } 55 | 56 | int main() { 57 | int n, k; 58 | scanf("%d%d", &n, &k); 59 | memset(visit, false, sizeof(visit)); 60 | printf("%d\n", BFS(n, k)); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /Chapter9/9.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Find The Multiple 3 | * 题目来源:POJ 1426 4 | * 题目链接:http://poj.org/problem?id=1426 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | void BFS(int n) { 15 | queue myQueue; 16 | myQueue.push(1); //压入初始状态 17 | while (!myQueue.empty()) { 18 | long long current = myQueue.front(); 19 | myQueue.pop(); 20 | if (current % n == 0) { //查找成功 21 | printf("%lld\n", current); 22 | return ; 23 | } 24 | myQueue.push(current * 10); 25 | myQueue.push(current * 10 + 1); 26 | } 27 | return ; 28 | } 29 | 30 | int main() { 31 | int n; 32 | while (scanf("%d", &n) != EOF) { 33 | if (n == 0) { 34 | break; 35 | } 36 | BFS(n); 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /Chapter9/9.3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:A Knight's Journey 3 | * 题目来源:POJ 2488 4 | * 题目链接:http://poj.org/problem?id=2488 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const int MAXN = 30; //棋盘参数 16 | 17 | int direction[8][2] = { 18 | {-1, -2}, {1, -2}, {-2, -1}, {2, -1}, {-2, 1}, {2, 1}, {-1, 2}, {1, 2} 19 | }; 20 | 21 | bool visit[MAXN][MAXN]; //标记矩阵 22 | 23 | bool DFS(int x, int y, int step, string answer, int p, int q) { 24 | if (step == p * q) { //搜索成功 25 | cout << answer << endl << endl; 26 | return true; 27 | } 28 | for (int i = 0; i < 8; ++i) { //遍历邻居结点 29 | int nx = x + direction[i][0]; //扩展状态坐标 30 | int ny = y + direction[i][1]; 31 | if (nx < 0 || nx >= p || ny < 0 || ny >= q || visit[nx][ny]) { 32 | continue; 33 | } 34 | char col = ny + 'A'; //该点编号 35 | char row = nx + '1'; 36 | visit[nx][ny] = true; //标记该点 37 | if (DFS(nx, ny, step + 1, answer + col + row, p, q)) { 38 | return true; 39 | } 40 | visit[nx][ny] = false; //取消标记 41 | } 42 | return false; 43 | } 44 | 45 | int main() { 46 | int n; 47 | scanf("%d", &n); 48 | int caseNumber = 0; 49 | while (n--) { 50 | int p, q; 51 | scanf("%d%d", &p, &q); 52 | memset(visit, false, sizeof(visit)); 53 | cout << "Scenario #" << ++caseNumber << ":" << endl; 54 | visit[0][0] = true; //标记A1点 55 | if (!DFS(0, 0, 1, "A1", p, q)) { 56 | cout << "impossible" << endl << endl; 57 | } 58 | } 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Chapter9/9.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目名称:Square 3 | * 题目来源:POJ 2362 4 | * 题目链接:http://poj.org/problem?id=2362 5 | * 代码作者:杨泽邦(炉灰) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const int MAXN = 30; 16 | int sticks[MAXN]; 17 | bool visit[MAXN]; 18 | 19 | bool DFS(int sum, int number, int position, int side, int m) { 20 | if (number == 3) { 21 | return true; 22 | } 23 | int sample = 0; //剪枝(3) 24 | for (int i = position; i < m; ++i) { 25 | if (visit[i] || sum + sticks[i] > side || sticks[i] == sample) { 26 | continue; 27 | } 28 | visit[i] = true; 29 | if (sum + sticks[i] == side) { //凑成一条边 30 | if (DFS(0, number + 1, 0, side, m)) { 31 | return true; 32 | } else { 33 | sample = sticks[i]; //记录失败棍子长度 34 | } 35 | } else { 36 | if (DFS(sum + sticks[i], number, i + 1, side, m)) { 37 | return true; 38 | } else { 39 | sample = sticks[i]; //记录失败棍子长度 40 | } 41 | } 42 | visit[i] = false; 43 | } 44 | return false; 45 | } 46 | 47 | bool Compare(int x, int y) { 48 | return x > y; 49 | } 50 | 51 | int main() { 52 | int n; 53 | scanf("%d", &n); 54 | while (n--) { 55 | int m; 56 | scanf("%d", &m); //木棍数目 57 | int length = 0; //总长 58 | for (int i = 0; i < m; ++i) { 59 | scanf("%d", &sticks[i]); 60 | length += sticks[i]; 61 | } 62 | memset(visit, false, sizeof(visit)); 63 | if (length % 4 != 0) { //剪枝(1) 64 | printf("no\n"); 65 | continue; 66 | } 67 | int side = length / 4; //边长 68 | sort(sticks, sticks + m, Compare); //从大到小排序 69 | if (sticks[0] > side) { //剪枝(2) 70 | printf("no\n"); 71 | continue; 72 | } 73 | if (DFS(0, 0, 0, side, m)) { 74 | printf("yes\n"); 75 | } else { 76 | printf("no\n"); 77 | } 78 | } 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 王道考研机试指南(第二版) 例题代码 2 | 3 | 大家好,我是王道考研机试指南(第二版)的作者炉灰。 4 | 5 | 我将本书所有的例题代码都提交到GitHub上进行托管,大家可以自行查看、学习和下载。 6 | 7 | 点击**Star**进行收藏,以方便之后进行查看。 8 | 9 | 点击**Watch**保持关注,如代码有后续更新,会第一时间收到通知。 10 | 11 | 点击**Fork**克隆到自己的GitHub下,如有bug,请使用**Issues**和我进行讨论;如有修改意见,请使用**Pull requests**提交你的修改意见。 12 | 13 | **如出现书中代码与GitHub代码不一致的情况,以GitHub的代码为准。** 14 | 15 | 祝各位考生考上自己心仪的院校!!! 16 | 17 | 题目以及链接 18 | 19 | | 题目编号 | 题目名称 | 题目链接 | 参考代码 | 20 | |:--------:|:-----------:|:-------------------------------------------:|:-------------------------------------------:| 21 | | 例题1.1 | A+B (HDU 1089) | http://acm.hdu.edu.cn/showproblem.php?pid=1089 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter1/1.1.cpp| 22 | | 例题2.1 | abc (清华大学复试上机题) | http://t.cn/E9WMRTE | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.1.cpp| 23 | | 例题2.2 | 反序数 (清华大学复试上机题) | http://t.cn/E9WBrut | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.2.cpp| 24 | | 例题2.3 | 对称平方数1 (清华大学复试上机题) | http://t.cn/E9lUYRn | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.3.cpp| 25 | | 例题2.4 | 输出梯形 (清华大学复试上机题) | | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.4.cpp| 26 | | 例题2.5 | 叠筐 (HDU 2074) | http://acm.hdu.edu.cn/showproblem.php?pid=2074 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.5.cpp| 27 | | 例题2.6 | 今年的第几天? (清华大学复试上机题) | http://t.cn/E9jXK5A | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.6.cpp| 28 | | 例题2.7 | 打印日期 (华中科技大学复试上机题) | http://t.cn/E9YP2a8 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.7.cpp| 29 | | 例题2.8 | 日期累加 (北京理工大学复试上机题) | http://t.cn/E9Yw0Cr | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.8.cpp| 30 | | 例题2.9 | 剩下的树 (清华大学复试上机题) | http://t.cn/E9ufYo5 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.9.cpp| 31 | | 例题2.10 | 手机键盘 (清华大学复试上机题) | http://t.cn/E9ulcIc | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.10.cpp| 32 | | 例题2.11 | XXX定律 (浙江大学复试上机题) | http://t.cn/E937wDs | https://github.com/BenedictYoung/Lecture/blob/master/Chapter2/2.11.cpp| 33 | | 例题3.1 | 排序 (清华大学复试上机题) | http://t.cn/E9dLx5K | https://github.com/BenedictYoung/Lecture/blob/master/Chapter3/3.1.cpp| 34 | | 例题3.2 | 成绩排序 (清华大学复试上机题) | http://t.cn/E9d3ysv | https://github.com/BenedictYoung/Lecture/blob/master/Chapter3/3.2.cpp| 35 | | 例题3.3 | 成绩排序2 (清华大学复试上机题) | http://t.cn/E9gyHM1 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter3/3.3.cpp| 36 | | 例题3.4 | 找x (哈尔滨工业大学复试上机题) | http://t.cn/E9gHFnS | https://github.com/BenedictYoung/Lecture/blob/master/Chapter3/3.4.cpp| 37 | | 例题3.5 | 查找 (北京邮电大学复试上机题) | http://t.cn/E9g8aaR | https://github.com/BenedictYoung/Lecture/blob/master/Chapter3/3.5.cpp| 38 | | 例题4.1 | 特殊乘法 (清华大学复试上机题) | http://t.cn/Ai8by9vW | https://github.com/BenedictYoung/Lecture/blob/master/Chapter4/4.1.cpp| 39 | | 例题4.2 | 密码翻译 (北京大学复试上机题) | http://t.cn/Ai8bGaIx | https://github.com/BenedictYoung/Lecture/blob/master/Chapter4/4.2.cpp| 40 | | 例题4.3 | 简单密码 (北京大学复试上机题) | http://t.cn/Ai8bih2z | https://github.com/BenedictYoung/Lecture/blob/master/Chapter4/4.3.cpp| 41 | | 例题4.4 | 统计字符 (浙江大学复试上机题) | http://t.cn/Ai8fvq4I | https://github.com/BenedictYoung/Lecture/blob/master/Chapter4/4.4.cpp| 42 | | 例题4.5 | 字母统计 (上海交通大学复试上机题) | http://t.cn/Ai8VB72e | https://github.com/BenedictYoung/Lecture/blob/master/Chapter4/4.5.cpp| 43 | | 例题4.6 | Number Sequence (HDU 1711) | http://acm.hdu.edu.cn/showproblem.php?pid=1711 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter4/4.6.cpp| 44 | | 例题4.7 | Oulipo (POJ 3461) | http://poj.org/problem?id=3461 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter4/4.7.cpp| 45 | | 例题5.1 | 完数与盈数 (清华大学复试上机题) | http://t.cn/AiKEyQWW | https://github.com/BenedictYoung/Lecture/blob/master/Chapter5/5.1.cpp| 46 | | 例题5.2 | 约瑟夫问题NO.2 (Bailian 3254) | http://bailian.openjudge.cn/practice/3254 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter5/5.2.cpp| 47 | | 例题5.3 | 猫狗收容所 | | https://github.com/BenedictYoung/Lecture/blob/master/Chapter5/5.3.cpp| 48 | | 例题5.4 | Zero-complexity Transposition (上海交通大学复试上机题) | http://t.cn/AiKa20bt | https://github.com/BenedictYoung/Lecture/blob/master/Chapter5/5.4.cpp| 49 | | 例题5.5 | 括号匹配问题 (CCNU 1978) | http://ccnu.openjudge.cn/practice/1978/ | https://github.com/BenedictYoung/Lecture/blob/master/Chapter5/5.5.cpp| 50 | | 例题5.6 | 简单计算器 (浙江大学复试上机题) | http://t.cn/AiKoGS94 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter5/5.6.cpp| 51 | | 例题6.1 | 二进制数 (北京邮电大学复试上机题) | http://t.cn/AiCuKTOv | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.1.cpp| 52 | | 例题6.2 | 进制转换 (清华大学复试上机题) | http://t.cn/AiCuoPRO | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.2.cpp| 53 | | 例题6.3 | 十进制与二进制 (清华大学复试上机题) | http://t.cn/AiCuoHKg | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.3.cpp| 54 | | 例题6.4 | 进制转换2 (清华大学复试上机题) | http://t.cn/AiCuKG7E | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.4.cpp| 55 | | 例题6.5 | 最大公约数 (哈尔滨工业大学复试上机题) | http://t.cn/AiCuWLTS | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.5.cpp| 56 | | 例题6.6 | 最小公倍数 (HDU 1108) | http://acm.hdu.edu.cn/showproblem.php?pid=1108 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.6.cpp| 57 | | 例题6.7 | 素数判定 (哈尔滨工业大学复试上机题) | http://t.cn/AiCuWE0Q | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.7.cpp| 58 | | 例题6.8 | 素数 (北京航空航天大学复试上机题) | http://t.cn/AiCulqtW | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.8.cpp| 59 | | 例题6.9 | 质因数的个数 (清华大学复试上机题) | http://t.cn/Aip7J0Oo | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.9.cpp| 60 | | 例题6.10 | 人见人爱A^B (HDU 2035) | http://acm.hdu.edu.cn/showproblem.php?pid=2035 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.10.cpp| 61 | | 例题6.11 | 计算两个矩阵的乘积 (哈尔滨工业大学复试上机题) | http://t.cn/Aip450PJ | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.11.cpp| 62 | | 例题6.12 | 矩阵幂 (北京邮电大学复试上机题) | http://t.cn/Aip4T3HX | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.12.cpp| 63 | | 例题6.13 | a+b (华中科技大学复试上机题) | http://t.cn/AipaWiSG | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.13.cpp| 64 | | 例题6.14 | N的阶乘 (清华大学复试上机题) | http://t.cn/AipaBKQJ | https://github.com/BenedictYoung/Lecture/blob/master/Chapter6/6.14.cpp| 65 | | 例题7.1 | 鸡兔同笼 (北京大学复试上机题) | http://t.cn/E9ewERU | https://github.com/BenedictYoung/Lecture/blob/master/Chapter7/7.1.cpp| 66 | | 例题7.2 | FatMouse' Trade (HDU 1009) | http://acm.hdu.edu.cn/showproblem.php?pid=1009 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter7/7.2.cpp| 67 | | 例题7.3 | Senior's Gun (HDU 5281) | http://acm.hdu.edu.cn/showproblem.php?pid=5281 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter7/7.3.cpp| 68 | | 例题7.4 | 今年暑假不AC (HDU 2037) | http://acm.hdu.edu.cn/showproblem.php?pid=2037 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter7/7.4.cpp| 69 | | 例题7.5 | Case of Fugitive (Codeforces 555B) | http://codeforces.com/problemset/problem/555/B | https://github.com/BenedictYoung/Lecture/blob/master/Chapter7/7.5.cpp| 70 | | 例题8.1 | n的阶乘 (清华大学复试上机题) | http://t.cn/Ai0ocOUY | https://github.com/BenedictYoung/Lecture/blob/master/Chapter8/8.1.cpp| 71 | | 例题8.2 | 汉诺塔Ⅲ (HDU 2064) | http://acm.hdu.edu.cn/showproblem.php?pid=2064 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter8/8.2.cpp| 72 | | 例题8.3 | Fibonacci (上海交通大学复试上机题) | http://t.cn/Ai0K3tU5 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter8/8.3.cpp| 73 | | 例题8.4 | 二叉树 (北京大学复试上机题 ) | http://t.cn/Ai0Ke6I0 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter8/8.4.cpp| 74 | | 例题9.1 | Catch That Cow (POJ 3278) | http://poj.org/problem?id=3278 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter9/9.1.cpp| 75 | | 例题9.2 | Find The Multiple (POJ 1426) | http://poj.org/problem?id=1426 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter9/9.2.cpp| 76 | | 例题9.3 | A Knights's Journey (POJ 2488) | http://poj.org/problem?id=2488 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter9/9.3.cpp| 77 | | 例题9.4 | Square (POJ 2362) | http://poj.org/problem?id=2362 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter9/9.4.cpp| 78 | | 例题10.1 | 二叉树遍历 (清华大学复试上机题) | http://t.cn/AiKuUTlX | https://github.com/BenedictYoung/Lecture/blob/master/Chapter10/10.1.cpp| 79 | | 例题10.2 | 二叉树遍历 (华中科技大学复试上机题) | http://t.cn/AiKgDfLU | https://github.com/BenedictYoung/Lecture/blob/master/Chapter10/10.2.cpp| 80 | | 例题10.3 | 二叉排序树 (华中科技大学复试上机题) | http://t.cn/Ai9PAkkv | https://github.com/BenedictYoung/Lecture/blob/master/Chapter10/10.3.cpp| 81 | | 例题10.4 | 二叉排序树 (华中科技大学复试上机题) | http://t.cn/AiKD0L5V | https://github.com/BenedictYoung/Lecture/blob/master/Chapter10/10.4.cpp| 82 | | 例题10.5 | 复数集合 (北京邮电大学复试上机题) | http://t.cn/Ai98yYlt | https://github.com/BenedictYoung/Lecture/blob/master/Chapter10/10.5.cpp| 83 | | 例题10.6 | 哈夫曼树 (北京邮电大学复试上机题) | http://t.cn/AiCuGMki | https://github.com/BenedictYoung/Lecture/blob/master/Chapter10/10.6.cpp| 84 | | 例题10.7 | 查找学生信息 (清华大学复试上机题) | http://t.cn/AiCuVIuY | https://github.com/BenedictYoung/Lecture/blob/master/Chapter10/10.7.cpp| 85 | | 例题10.8 | 魔咒词典 (浙江大学复试上机题) | http://t.cn/AiCufczt | https://github.com/BenedictYoung/Lecture/blob/master/Chapter10/10.8.cpp| 86 | | 例题10.9 | 字串计算 (北京大学复试上机题) | http://t.cn/AiCuJtI5 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter10/10.9.cpp| 87 | | 例题11.1 | 畅通工程 (浙江大学复试上机题) | http://t.cn/AiOvBHj9 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.1.cpp| 88 | | 例题11.2 | 连通图 (吉林大学复试上机题) | http://t.cn/AiO77VoA | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.2.cpp| 89 | | 例题11.3 | Is It A Tree? (北京大学复试上机题) | http://t.cn/AiO7FyDO | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.3.cpp| 90 | | 例题11.4 | 还是畅通工程 (浙江大学复试上机题) | http://t.cn/AiWud0C6 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.4.cpp| 91 | | 例题11.5 | 继续畅通工程 (浙江大学复试上机题) | http://t.cn/AiW3fcfp | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.5.cpp| 92 | | 例题11.6 | 畅通工程续 (浙江大学复试上机题) | http://acm.hdu.edu.cn/showproblem.php?pid=1874 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.6.cpp| 93 | | 例题11.7 | 最短路径问题 (浙江大学复试上机题) | http://t.cn/AilPbME2 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.7.cpp| 94 | | 例题11.8 | Legal or Not (HDU 3342) | http://acm.hdu.edu.cn/showproblem.php?pid=3342 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.8.cpp| 95 | | 例题11.9 | 确定比赛名次 (HUD 1285) | http://acm.hdu.edu.cn/showproblem.php?pid=1285 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.9.cpp| 96 | | 例题11.10 | Instructions Arrangement (HDU 4109) | http://acm.hdu.edu.cn/showproblem.php?pid=4109 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.10.cpp| 97 | | 例题11.11 | p3 (清华大学复试上机题) | | https://github.com/BenedictYoung/Lecture/blob/master/Chapter11/11.11.cpp| 98 | | 例题12.1 | N阶楼梯上楼问题 (华中科技大学复试上机题) | http://t.cn/Aij9Fr3V | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.1.cpp| 99 | | 例题12.2 | 最大序列和 (清华大学复试上机题) | http://t.cn/AiYSlQMU | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.2.cpp| 100 | | 例题12.3 | 最大子矩阵 (北京大学复试上机题) | http://t.cn/AiYSemJz | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.3.cpp| 101 | | 例题12.4 | 拦截导弹 (北京大学复试上机题) | http://t.cn/AiYCeV3m | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.4.cpp| 102 | | 例题12.5 | 最长上升子序列和 (北京大学复试上机题) |http://t.cn/AiYNAGD3 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.5.cpp| 103 | | 例题12.6 | Common Subsequence (HDU 1159) | http://acm.hdu.edu.cn/showproblem.php?pid=1159 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.6.cpp| 104 | | 例题12.7 | 点菜问题 (北京大学复试上机题) | http://t.cn/AiYOrkXr | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.7.cpp| 105 | | 例题12.8 | Piggy-Bank (HDU 1114) | http://acm.hdu.edu.cn/showproblem.php?pid=1114 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.8.cpp| 106 | | 例题12.9 | 珍惜现在,感恩生活 (HDU 2191) | http://acm.hdu.edu.cn/showproblem.php?pid=2191 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.9.cpp| 107 | | 例题12.10 | The Triangle (POJ 1163) | http://poj.org/problem?id=1163 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.10.cpp| 108 | | 例题12.11 | Monkey Banana problemset (LightOJ 1104) | http://lightoj.com/volume_showproblem.php?problem=1004 | https://github.com/BenedictYoung/Lecture/blob/master/Chapter12/12.11.cpp| 109 | --------------------------------------------------------------------------------