├── LeetCode ├── LeetCode1021:删除最外层的括号.cpp ├── LeetCode1252:奇数值单元格的数目.cpp ├── LeetCode1266:访问所有点的最小时间.cpp ├── LeetCode1290:二进制链表转整数.cpp ├── LeetCode1:两数之和.cpp ├── LeetCode461:汉明距离.cpp ├── LeetCode617:合并二叉树.cpp ├── LeetCode832:翻转图像.cpp ├── LeetCode938:二叉搜索树的范围和.cpp ├── 剑指 Offer 04. 二维数组中的查找.cpp ├── 剑指 Offer 05. 替换空格.cpp ├── 剑指 Offer 06. 从尾到头打印链表.cpp ├── 剑指 Offer 09. 用两个栈实现队列.cpp ├── 剑指 Offer 24. 反转链表.cpp ├── 剑指 Offer 30. 包含min函数的栈.cpp ├── 剑指 Offer 58 - II. 左旋转字符串.cpp └── 剑指 Offer 59 - I. 滑动窗口的最大值.cpp ├── LintCode ├── LintCode 219. 在排序链表中插入一个节点.cpp ├── LintCode 466. 链表节点计数.cpp ├── LintCode 53. 翻转字符串中的单词.cpp ├── LintCode 56. 两数之和.cpp ├── LintCode 60. 搜索插入位置.cpp ├── LintCode 82. 落单的数.cpp ├── LintCode 822. 相反的顺序存储.cpp ├── LintCode 920.会议室.cpp └── LintCode 去除重复元素.cpp ├── README.md ├── poj ├── poj1328:Radar Installation.cpp ├── poj3190:Stall Reservations.cpp ├── poj3273:花费.cpp └── poj3614:Sunscreen.cpp ├── 二分法 ├── poj1650:近似整数.cpp ├── 求最小自然数n满足阶乘尾0.cpp ├── 趋近法+数学解阶乘尾0.cpp └── 逃亡.cpp ├── 分治法 ├── 循环比赛安排.cpp └── 递归求解循环比赛.cpp ├── 博弈论 ├── bzoj1022:反sg游戏 SJ定理.cpp ├── hdu1527:威佐夫博弈.cpp ├── hdu1846:巴什博弈.cpp ├── hdu1847:SG函数.cpp ├── hdu1848:SG函数+尼姆博弈.cpp ├── hdu1850:尼姆博弈.cpp ├── hdu2149:巴什博弈2.cpp ├── hdu2516:斐波那契博弈.cpp ├── wannafly挑战赛23 游戏:SG函数.cpp └── 栗酱的异或和:尼姆博弈.cpp ├── 图论 └── prim算法:nyoj布线工程.cpp ├── 字符串 └── uva1588:换低档装置.cpp ├── 快速幂 ├── 位运算优化快速幂算法.cpp ├── 基本快速幂算法.cpp └── 快速幂取模运算.cpp ├── 排序 └── 快速选择算法:求无序数组中第k大的数.cpp ├── 搜索 ├── n皇后问题.cpp ├── 使用栈模拟递归.cpp └── 马踏棋盘.cpp ├── 数据结构 ├── 南阳oj35:逆波兰表达式.cpp ├── 双端队列:栗酱简单的数据结构.cpp ├── 多项式乘法.cpp ├── 多项式相加.cpp ├── 邻接矩阵写法:求树的直径:大臣的旅费.cpp ├── 邻接矩阵第二种写法:求树的直径:大臣的旅费.cpp └── 邻接表写法:大臣的旅费.cpp ├── 数论 ├── bzoj1257:余数之和(分块枚举).cpp └── 收敛极限:icpc水题crue.cpp ├── 最小生成树 ├── hdu1863:畅通工程(kruskal算法).cpp ├── hdu1863:畅通工程(prim算法).cpp ├── 洛谷P3366:kruskal算法模板题.cpp └── 洛谷P3366:prim算法模板题.cpp ├── 杂项 └── uva1587:盒子.cpp ├── 枚举 └── bzoj1800:飞行棋.cpp ├── 模拟 ├── 递推:小杰的签到题.cpp └── 队列模拟法:小杰的签到题.cpp ├── 洛谷 └── 洛谷P3366:kruskal算法模板题.cpp ├── 离散化处理 └── bzoj1303:中位数图.cpp ├── 计算几何 ├── poj2507:计算几何+二分.cpp └── 裁缝大师:求园内正多边形的顶点.cpp ├── 读入挂 └── 读入挂.cpp ├── 题解 └── atcoder beginnner contest 187.md └── 高精度 ├── uva11809:浮点数.cpp └── uva202:循环小数.cpp /LeetCode/LeetCode1021:删除最外层的括号.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string removeOuterParentheses(string S) { 4 | string str; 5 | int l = 1, r = 0; 6 | for(int i = 1; i < S.size(); ++i) { 7 | if(S[i] == '(') l++; 8 | if(S[i] == ')') r++; 9 | if(l != r) str.push_back(S[i]); 10 | else { 11 | l = 1, r = 0, ++i; 12 | } 13 | } 14 | return str; 15 | } 16 | }; -------------------------------------------------------------------------------- /LeetCode/LeetCode1252:奇数值单元格的数目.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 思路,统计行和列上为奇数的情况,观察值,只有当行列为一奇一偶对应位置上的值才是奇数。 3 | 最后运用排列组合,res = 行奇*列偶 + 行偶 * 列奇 4 | 其中行偶 = n - 行奇, 列偶 = m - 列奇 5 | */ 6 | 7 | class Solution { 8 | public: 9 | int row[105], col[105]; 10 | int oddCells(int n, int m, vector>& indices) { 11 | for(int i = 0; i < indices.size(); ++i) { 12 | ++row[indices[i][0]], ++col[indices[i][1]]; 13 | } 14 | int odd_row = 0, odd_col = 0; 15 | for(int i = 0; i < n; ++i) 16 | if(row[i] & 1) ++odd_row; 17 | for(int i = 0; i < m; ++i) 18 | if(col[i] & 1) ++odd_col; 19 | return odd_row * (m - odd_col) + odd_col * (n - odd_row); 20 | } 21 | }; -------------------------------------------------------------------------------- /LeetCode/LeetCode1266:访问所有点的最小时间.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 思路:切比雪夫距离,两点间的距离为max(abs(x1-x2), abs(y1-y2)). 3 | */ 4 | 5 | class Solution { 6 | public: 7 | int minTimeToVisitAllPoints(vector>& points) { 8 | int dis = 0; 9 | for(int i = 0; i < points.size() - 1; ++i) { 10 | dis += max(abs(points[i][0] - points[i + 1][0]), abs(points[i][1] - points[i + 1][1])); 11 | } 12 | return dis; 13 | } 14 | }; -------------------------------------------------------------------------------- /LeetCode/LeetCode1290:二进制链表转整数.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode(int x) : val(x), next(NULL) {} 7 | * }; 8 | */ 9 | 10 | /* 11 | 解法一:直接模拟法 12 | */ 13 | class Solution { 14 | public: 15 | int getDecimalValue(ListNode* head) { 16 | int res = 0; 17 | while(head) { 18 | res = res * 2 + head->val; 19 | head = head->next; 20 | } 21 | return res; 22 | } 23 | }; 24 | 25 | /* 26 | 解法二:位运算法: 27 | */ 28 | 29 | /** 30 | * Definition for singly-linked list. 31 | * struct ListNode { 32 | * int val; 33 | * ListNode *next; 34 | * ListNode(int x) : val(x), next(NULL) {} 35 | * }; 36 | */ 37 | class Solution { 38 | public: 39 | int getDecimalValue(ListNode* head) { 40 | int res = 0; 41 | while(head) { 42 | res = (res << 1) | head->val; 43 | head = head->next; 44 | } 45 | return res; 46 | } 47 | }; -------------------------------------------------------------------------------- /LeetCode/LeetCode1:两数之和.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector twoSum(vector& nums, int target) { 4 | unordered_map record; 5 | for(int i =0;i < nums.size();i++){ 6 | int com = target - nums[i]; 7 | if(record.find(com) != record.end()){ 8 | int res[2] = {i,record[com]}; 9 | return vector(res,res+2); 10 | } 11 | record[nums[i]] = i; 12 | } 13 | return vector(); 14 | } 15 | }; -------------------------------------------------------------------------------- /LeetCode/LeetCode461:汉明距离.cpp: -------------------------------------------------------------------------------- 1 | // 解法一:异或+lowbit 2 | class Solution { 3 | public: 4 | int hammingDistance(int x, int y) { 5 | int t = x ^ y; 6 | int cnt = 0; 7 | while(t) { 8 | cnt++; 9 | t -= t & (-t); 10 | } 11 | return cnt; 12 | } 13 | }; 14 | 15 | // 解法二:异或+bitset 16 | class Solution { 17 | public: 18 | int hammingDistance(int x, int y) { 19 | return bitset<32> (x ^ y).count(); 20 | } 21 | }; -------------------------------------------------------------------------------- /LeetCode/LeetCode617:合并二叉树.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | * }; 9 | */ 10 | class Solution { 11 | public: 12 | TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { 13 | if(t1 == nullptr && t2 == nullptr) return nullptr; 14 | if(t1 == nullptr) return t2; 15 | if(t2 == nullptr) return t1; 16 | 17 | TreeNode* newNode = new TreeNode(t1->val + t2->val); 18 | newNode->left = mergeTrees(t1->left, t2->left); 19 | newNode->right = mergeTrees(t1->right, t2->right); 20 | return newNode; 21 | } 22 | }; -------------------------------------------------------------------------------- /LeetCode/LeetCode832:翻转图像.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector> flipAndInvertImage(vector>& A) { 4 | int n = A.size(), m = A[0].size(); 5 | for(int i = 0; i < n; ++i) { 6 | for(int j = 0; j < m / 2; ++j) { 7 | A[i][j] ^= 1, A[i][m - j - 1] ^= 1; 8 | swap(A[i][j], A[i][m - j - 1]); 9 | } 10 | if(n & 1) A[i][m / 2 ] ^= 1; 11 | } 12 | return A; 13 | } 14 | }; -------------------------------------------------------------------------------- /LeetCode/LeetCode938:二叉搜索树的范围和.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 我们对树进行深度优先搜索,对于当前节点 node,如果 node.val 小于等于 L,那么只需要继续搜索它的右子树; 3 | 如果 node.val 大于等于 R,那么只需要继续搜索它的左子树;如果 node.val 在区间 (L, R) 中,则需要搜索它的所有子树。 4 | 5 | 6 | 下面是dfs的代码。 7 | 8 | 9 | */ 10 | 11 | 12 | 13 | /** 14 | * Definition for a binary tree node. 15 | * struct TreeNode { 16 | * int val; 17 | * TreeNode *left; 18 | * TreeNode *right; 19 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 20 | * }; 21 | */ 22 | class Solution { 23 | public: 24 | int ans; 25 | int rangeSumBST(TreeNode* root, int L, int R) { 26 | ans = 0; 27 | dfs(root, L, R); 28 | return ans; 29 | } 30 | void dfs(TreeNode* node, int L, int R) { 31 | if(node == nullptr) return ; 32 | if(L <= node->val && node->val <= R) ans += node->val; 33 | if(L < node->val) 34 | dfs(node->left, L, R); 35 | if(R > node->val) 36 | dfs(node->right, L, R); 37 | } 38 | }; -------------------------------------------------------------------------------- /LeetCode/剑指 Offer 04. 二维数组中的查找.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 因为二维数组每一行是有序的,我们每次遍历一行,然后对每一行进行二分查找即可。 3 | */ 4 | 5 | 6 | class Solution { 7 | public: 8 | bool findNumberIn2DArray(vector>& matrix, int target) { 9 | for(auto &x: matrix) { 10 | if(binary_search(x.begin(), x.end(), target)) 11 | return true; 12 | } 13 | return false; 14 | } 15 | }; -------------------------------------------------------------------------------- /LeetCode/剑指 Offer 05. 替换空格.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 每次查找空格的位置,然后用replace函数替换就行了,C++没有java和python方便,需要边查询边替换 3 | */ 4 | 5 | class Solution { 6 | public: 7 | string replaceSpace(string s) { 8 | int pos = -1; 9 | while((pos = s.find(" ")) != string::npos) { 10 | s.replace(pos, 1, "%20"); 11 | } 12 | return s; 13 | } 14 | }; -------------------------------------------------------------------------------- /LeetCode/剑指 Offer 06. 从尾到头打印链表.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 因为需要倒序,所以我们写一个递归即可,也可以遍历一遍再把vector给reverse。 3 | */ 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * struct ListNode { 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int x) : val(x), next(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | vector reversePrint(ListNode* head) { 16 | vector ans; 17 | print(head, ans); 18 | return ans; 19 | } 20 | void print(ListNode* head, vector &ans) { 21 | if(!head) return; 22 | print(head->next, ans); 23 | ans.push_back(head->val); 24 | } 25 | }; -------------------------------------------------------------------------------- /LeetCode/剑指 Offer 09. 用两个栈实现队列.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 声明两个栈,插入时直接插入到s1栈上,删除时,如果s2不为空,则直接弹出s2的栈顶元素, 3 | 否则先将s1中所有元素入栈s2中,然后再弹出栈顶元素。 4 | */ 5 | 6 | class CQueue { 7 | public: 8 | stack s1, s2; 9 | CQueue() { 10 | } 11 | 12 | void appendTail(int value) { 13 | s1.push(value); 14 | } 15 | 16 | int deleteHead() { 17 | if(!s1.size() && !s2.size()) return -1; 18 | if(!s2.size()) { 19 | while(s1.size()) { 20 | s2.push(s1.top()); s1.pop(); 21 | } 22 | } 23 | 24 | int res = s2.top(); 25 | s2.pop(); 26 | return res; 27 | } 28 | }; 29 | 30 | /** 31 | * Your CQueue object will be instantiated and called as such: 32 | * CQueue* obj = new CQueue(); 33 | * obj->appendTail(value); 34 | * int param_2 = obj->deleteHead(); 35 | */ -------------------------------------------------------------------------------- /LeetCode/剑指 Offer 24. 反转链表.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 定义一个prev指针存储逆置后的链表,一个curr存储当前节点,在循环中为了防止下一个节点丢失,定义一个next 3 | 存储curr的下一个节点,然后使用链表的头插法将当前节点插入curr即可。 4 | */ 5 | 6 | 7 | 8 | /** 9 | * Definition for singly-linked list. 10 | * struct ListNode { 11 | * int val; 12 | * ListNode *next; 13 | * ListNode(int x) : val(x), next(NULL) {} 14 | * }; 15 | */ 16 | class Solution { 17 | public: 18 | ListNode* reverseList(ListNode* head) { 19 | ListNode *prev = nullptr; 20 | ListNode *curr = head; 21 | while(curr) { 22 | ListNode *next = curr->next; 23 | curr->next = prev; 24 | prev = curr; 25 | curr = next; 26 | } 27 | return prev; 28 | } 29 | }; -------------------------------------------------------------------------------- /LeetCode/剑指 Offer 30. 包含min函数的栈.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 使用一个单调栈,记录一个非降序序列(可能最小值有多个),这样,如果插入的元素比栈顶元素小,则入栈,出栈时,因为后进先出, 3 | 所以最小值一定在次小值之前出栈了。 4 | */ 5 | 6 | class MinStack { 7 | public: 8 | /** initialize your data structure here. */ 9 | stack s, s1; 10 | MinStack() { 11 | } 12 | 13 | void push(int x) { 14 | s.push(x); 15 | if(!s1.size() || s1.top() >= x) s1.push(x); 16 | } 17 | 18 | void pop() { 19 | if(s.top() == s1.top()) 20 | s1.pop(); 21 | s.pop(); 22 | } 23 | 24 | int top() { 25 | return s.top(); 26 | } 27 | 28 | int min() { 29 | return s1.top(); 30 | } 31 | }; 32 | 33 | /** 34 | * Your MinStack object will be instantiated and called as such: 35 | * MinStack* obj = new MinStack(); 36 | * obj->push(x); 37 | * obj->pop(); 38 | * int param_3 = obj->top(); 39 | * int param_4 = obj->min(); 40 | */ -------------------------------------------------------------------------------- /LeetCode/剑指 Offer 58 - II. 左旋转字符串.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 先将前k个字符逆置,再将后n - k个字符逆置,再将整个字符串逆置,即可得到答案。 3 | */ 4 | 5 | 6 | 7 | class Solution { 8 | public: 9 | string reverseLeftWords(string s, int n) { 10 | reverse(s.begin(), s.begin() + n); 11 | reverse(s.begin() + n, s.end()); 12 | reverse(s.begin(), s.end()); 13 | return s; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /LeetCode/剑指 Offer 59 - I. 滑动窗口的最大值.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 单调队列经典题目,维护一个双端队列,保持其队头永远是最大值的索引即可。 3 | */ 4 | 5 | 6 | class Solution { 7 | public: 8 | vector maxSlidingWindow(vector& nums, int k) { 9 | vector ans; 10 | deque dq; 11 | for(int i = 0; i < nums.size(); i++) { 12 | while(dq.size() && nums[dq.back()] < nums[i]) dq.pop_back(); // 让新的最(次)大值能尽量靠近队头 13 | if(dq.size() && dq.front() < i - k + 1) dq.pop_front(); // 清除掉队头过期的索引 14 | dq.push_back(i); 15 | if(i >= k - 1) ans.push_back(nums[dq.front()]); 16 | } 17 | return ans; 18 | } 19 | }; -------------------------------------------------------------------------------- /LintCode/LintCode 219. 在排序链表中插入一个节点.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 因为链表是排好序的,遍历查找插入位置,然后新建节点插入即可。 3 | */ 4 | 5 | /** 6 | * Definition of singly-linked-list: 7 | * class ListNode { 8 | * public: 9 | * int val; 10 | * ListNode *next; 11 | * ListNode(int val) { 12 | * this->val = val; 13 | * this->next = NULL; 14 | * } 15 | * } 16 | */ 17 | 18 | class Solution { 19 | public: 20 | /** 21 | * @param head: The head of linked list. 22 | * @param val: An integer. 23 | * @return: The head of new linked list. 24 | */ 25 | ListNode * insertNode(ListNode * head, int val) { 26 | ListNode *Node = new ListNode(0); 27 | Node->next = head; 28 | ListNode *p = Node; 29 | while(p) { 30 | ListNode *next = p->next; 31 | if(next && next->val < val) { 32 | p = p->next; 33 | } else { 34 | ListNode *q = new ListNode(val); 35 | q->next = next; 36 | p->next = q; 37 | break; 38 | } 39 | } 40 | return Node->next; 41 | } 42 | }; -------------------------------------------------------------------------------- /LintCode/LintCode 466. 链表节点计数.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 遍历一遍即可。 3 | */ 4 | 5 | /** 6 | * Definition of singly-linked-list: 7 | * class ListNode { 8 | * public: 9 | * int val; 10 | * ListNode *next; 11 | * ListNode(int val) { 12 | * this->val = val; 13 | * this->next = NULL; 14 | * } 15 | * } 16 | */ 17 | 18 | class Solution { 19 | public: 20 | /** 21 | * @param head: the first node of linked list. 22 | * @return: An integer 23 | */ 24 | int countNodes(ListNode * head) { 25 | int totNode = 0; 26 | while(head) { 27 | totNode++; 28 | head = head->next; 29 | } 30 | return totNode; 31 | } 32 | }; -------------------------------------------------------------------------------- /LintCode/LintCode 53. 翻转字符串中的单词.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 在C++中,因为没有split和trim这种好用的字符串处理函数,遇到这种问题我们可以使用stringsteam 3 | */ 4 | 5 | class Solution { 6 | public: 7 | /* 8 | * @param s: A string 9 | * @return: A string 10 | */ 11 | string reverseWords(string &s) { 12 | stringstream ss; 13 | string ans = "", tmp; 14 | ss << s; 15 | while(ss >> tmp) { 16 | ans = " " + tmp + ans; 17 | } 18 | if(ans.size()) 19 | ans.erase(ans.begin()); 20 | return ans; 21 | } 22 | }; -------------------------------------------------------------------------------- /LintCode/LintCode 56. 两数之和.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 有两个思路,一是使用map记录下数字对应的下标,直接查表就行, 3 | 二是使用二分查找,下面是第一种思路的代码。 4 | */ 5 | 6 | class Solution { 7 | public: 8 | /** 9 | * @param numbers: An array of Integer 10 | * @param target: target = numbers[index1] + numbers[index2] 11 | * @return: [index1 + 1, index2 + 1] (index1 < index2) 12 | */ 13 | vector twoSum(vector &numbers, int target) { 14 | unordered_map mmp, mmp1; 15 | for(int i = 0; i < numbers.size(); i++) { 16 | mmp[numbers[i]] = i; 17 | mmp1[numbers[i]] = true; 18 | } 19 | for(int i = 0; i < numbers.size(); i++) { 20 | int tmp = target - numbers[i]; 21 | if(mmp1[tmp]) { 22 | int p = mmp[tmp]; 23 | return {min(p, i), max(p, i)}; 24 | } 25 | } 26 | } 27 | }; -------------------------------------------------------------------------------- /LintCode/LintCode 60. 搜索插入位置.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 使用二分查找第一个大于等于该值的位置即可,下面使用了c++的lower_bound函数。 3 | 4 | */ 5 | 6 | class Solution { 7 | public: 8 | /** 9 | * @param A: an integer sorted array 10 | * @param target: an integer to be inserted 11 | * @return: An integer 12 | */ 13 | int searchInsert(vector &A, int target) { 14 | return lower_bound(A.begin(), A.end(), target) - A.begin(); 15 | } 16 | }; -------------------------------------------------------------------------------- /LintCode/LintCode 82. 落单的数.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 思路: 3 | 利用异或运算的特性,两次异或后仍为原数, a ^ x ^ x = a 4 | 将数组遍历一遍即可 5 | */ 6 | 7 | class Solution { 8 | public: 9 | /** 10 | * @param A: An integer array 11 | * @return: An integer 12 | */ 13 | int singleNumber(vector &A) { 14 | int ans = 0; 15 | for(auto x: A) { 16 | ans ^= x; 17 | } 18 | return ans; 19 | } 20 | }; -------------------------------------------------------------------------------- /LintCode/LintCode 822. 相反的顺序存储.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 顺序遍历一遍然后逆置就行。 3 | */ 4 | 5 | /** 6 | * Definition of singly-linked-list: 7 | * class ListNode { 8 | * public: 9 | * int val; 10 | * ListNode *next; 11 | * ListNode(int val) { 12 | * this->val = val; 13 | * this->next = NULL; 14 | * } 15 | * } 16 | */ 17 | 18 | class Solution { 19 | public: 20 | /** 21 | * @param head: the given linked list 22 | * @return: the array that store the values in reverse order 23 | */ 24 | vector reverseStore(ListNode * head) { 25 | vector ans; 26 | while(head) { 27 | ans.push_back(head->val); 28 | head = head->next; 29 | } 30 | reverse(ans.begin(), ans.end()); 31 | return ans; 32 | } 33 | }; -------------------------------------------------------------------------------- /LintCode/LintCode 920.会议室.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 贪心,按开始时间升序排序,然后遍历一遍即可,下面演示了sort使用匿名函数进行排序的方法。 3 | 4 | */ 5 | 6 | 7 | 8 | /** 9 | * Definition of Interval: 10 | * class Interval { 11 | * int start, end; 12 | * Interval(int start, int end) { 13 | * this->start = start; 14 | * this->end = end; 15 | * } 16 | * } 17 | */ 18 | 19 | 20 | class Solution { 21 | public: 22 | /** 23 | * @param intervals: an array of meeting time intervals 24 | * @return: if a person could attend all meetings 25 | */ 26 | bool canAttendMeetings(vector &intervals) { 27 | int last = -1; 28 | sort(intervals.begin(), intervals.end(), [](Interval a, Interval b) { 29 | return a.start < b.start; 30 | }); 31 | for(auto interval: intervals) { 32 | if (interval.start < last) return false; 33 | last = interval.end; 34 | } 35 | return true; 36 | } 37 | }; -------------------------------------------------------------------------------- /LintCode/LintCode 去除重复元素.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 我们可以使用一个set记录之前出现的元素,用一个idx变量记录去重的长度,如果当前元素没有出现,则 3 | 加入到数组中,并且让idx++。 4 | */ 5 | 6 | class Solution { 7 | public: 8 | /** 9 | * @param nums: an array of integers 10 | * @return: the number of unique integers 11 | */ 12 | int deduplication(vector &nums) { 13 | set st; 14 | int idx = 0; 15 | for(int i = 0; i < nums.size(); ++i) { 16 | if(!st.count(nums[i])) { 17 | nums[idx++] = nums[i]; 18 | } 19 | st.insert(nums[i]); 20 | } 21 | return idx; 22 | } 23 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ACM_Coding_Plan 2 | 📕ACM算法竞赛训练存档计划,目前已刷2300题左右。 3 | 4 | -------------------------------------------------------------------------------- /poj/poj1328:Radar Installation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | typedef long long ll; 6 | typedef pair P; 7 | const int MAXN = 1e3; 8 | const int INF = 0x3f3f3f3f; 9 | const double eps = 1e-6; 10 | int n, d, num; 11 | 12 | struct point { 13 | int x, y; 14 | double l, r; 15 | inline bool operator < (const point& x) const { 16 | return l < x.l; 17 | } 18 | } p[MAXN + 5]; 19 | 20 | void slove() 21 | { 22 | for(int i = 0; i < n; ++i) cin >> p[i].x >> p[i].y; 23 | bool flag = true; 24 | for(int i = 0; i < n; ++i) { 25 | if(p[i].y > d) { 26 | flag = false; 27 | break; 28 | } 29 | } 30 | if(!flag) { 31 | cout << "Case " << ++num << ": -1" << endl; 32 | return; 33 | } 34 | for(int i = 0; i < n; ++i) { 35 | double k = sqrt((double)d * d - (double)p[i].y * p[i].y); 36 | p[i].l = p[i].x - k, p[i].r = p[i].x + k; 37 | } 38 | sort(p, p + n); 39 | int ans = 1; 40 | double pos = INF; 41 | for(int i = 0; i < n; ++i) { 42 | if(pos + eps < p[i].l) { 43 | ans++; 44 | pos = p[i].r; 45 | } 46 | else pos = min(pos, p[i].r); 47 | } 48 | cout << "Case " << ++num << ": " << ans << endl; 49 | } 50 | 51 | int main() 52 | { 53 | while(cin >> n >> d, n) slove(); 54 | return 0; 55 | } -------------------------------------------------------------------------------- /poj/poj3190:Stall Reservations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | typedef long long ll; 6 | typedef pair P; 7 | const int MAXN = 5e4; 8 | int ans[MAXN + 5]; 9 | //poj3190:Stall Reservations 10 | struct node { 11 | int id, l, r, ans; 12 | inline bool operator < (const node& x) const { 13 | return l < x.l; 14 | } 15 | }cow[MAXN + 5]; 16 | 17 | int main() 18 | { 19 | ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 20 | int n; 21 | cin >> n; 22 | for(int i = 0; i < n; ++i) { 23 | cow[i].id = i; 24 | cin >> cow[i].l >> cow[i].r; 25 | } 26 | sort(cow, cow + n); 27 | priority_queue, greater

> q; 28 | for(int i = 0; i < n; ++i) { 29 | int num = q.size(); 30 | if(num && q.top().first < cow[i].l) { 31 | cow[i].ans = q.top().second; 32 | q.pop(); 33 | q.push({cow[i].r, cow[i].ans}); 34 | continue; 35 | } 36 | cow[i].ans = ++num; 37 | q.push({cow[i].r, num}); 38 | } 39 | cout << q.size() << endl; 40 | for(int i = 0; i < n; ++i) ans[cow[i].id] = cow[i].ans; 41 | for(int i = 0; i < n; ++i) cout << ans[i] << endl; 42 | return 0; 43 | } -------------------------------------------------------------------------------- /poj/poj3273:花费.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schrodingercatss/ACM_Coding_Plan/dda8a2d78525740cc49f246aae7cb2c9e40d6caa/poj/poj3273:花费.cpp -------------------------------------------------------------------------------- /poj/poj3614:Sunscreen.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | typedef long long ll; 4 | const int MAXN = 2500; 5 | struct Cow { 6 | int l, r; 7 | inline bool operator < (const Cow& x) const { 8 | return l < x.l; 9 | } 10 | }cow[MAXN + 5]; 11 | 12 | struct Spf { 13 | int s, c; 14 | inline bool operator < (const Spf& x) const { 15 | return s < x.s; 16 | } 17 | }spf[MAXN + 5]; 18 | 19 | int main() 20 | { 21 | int n, m; 22 | cin >> n >> m; 23 | for(int i = 1; i <= n; ++i) cin >> cow[i].l >> cow[i].r; 24 | for(int i = 1; i <= m; ++i) cin >> spf[i].s >> spf[i].c; 25 | sort(cow + 1, cow + n + 1); 26 | sort(spf + 1, spf + m + 1); 27 | int ans = 0, cur = 1; 28 | priority_queue, greater > q; 29 | for(int i = 1; i <= m; ++i) { 30 | while(cur <= n && cow[cur].l <= spf[i].s) q.push(cow[cur++].r); 31 | while(spf[i].c && q.size()) { 32 | int t = q.top(); q.pop(); 33 | if(t < spf[i].s) continue; 34 | ans++, spf[i].c--; 35 | } 36 | } 37 | cout << ans << endl; 38 | return 0; 39 | } -------------------------------------------------------------------------------- /二分法/poj1650:近似整数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define INF 0x3f3f3f3f 3 | using namespace std; 4 | void solve(double a,int l) 5 | { 6 | double minv=INF; 7 | int n=1,d=1; 8 | int t1=n,t2=d; 9 | while(n<=l&&d<=l){ 10 | double exp=a-(double)n/d; 11 | double exp1=fabs(exp); 12 | if(exp10)n++; 17 | else d++; 18 | } 19 | cout<>a>>l){ 26 | solve(a,l); 27 | } 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /二分法/求最小自然数n满足阶乘尾0.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schrodingercatss/ACM_Coding_Plan/dda8a2d78525740cc49f246aae7cb2c9e40d6caa/二分法/求最小自然数n满足阶乘尾0.cpp -------------------------------------------------------------------------------- /二分法/趋近法+数学解阶乘尾0.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *题目跟上一道一样,都是求最小自然数n满足阶乘尾0个数为q 3 | *这里我们可以用等比数列去优化它, Q=N/5+N/(5²)+N/(5³)..... =4Q*[(5^k)/(5^k-1)] 4 | *观察到,当k趋于无穷时,整个比例式趋于1,所以我们可以计算出N=4Q的末尾0个数,然后与Q进行比较 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | int solve(int n) 11 | { 12 | int ans=0; 13 | while(n){ 14 | n/=5; 15 | ans+=n; 16 | } 17 | return ans; 18 | } 19 | 20 | int main() 21 | { 22 | int n; 23 | while(cin>>n){ 24 | if(!n){cout<<1< 2 | #define ForMyLove return 0 3 | using namespace std; 4 | const int maxn = 100; 5 | char s[maxn + 5], t[maxn + 5]; 6 | 7 | int main() 8 | { 9 | int slen, tlen, ans1, ans2, i, j; 10 | while(cin>> s){ 11 | cin>> t; 12 | slen = strlen(s); 13 | tlen = strlen(t); 14 | 15 | //s在左,t在右 16 | for(i = 0; i < slen; ++i){ 17 | for(j = 0; j < tlen && i + j < slen; ++j){ //i + j < slen防止越界 18 | if(s[i + j] == '2' && t[j] =='2') 19 | break; 20 | } 21 | if(j == tlen || i + j == slen) 22 | break; 23 | } 24 | ans1 = i + tlen; 25 | if(ans1 2 | using namespace std; 3 | typedef long long ll; 4 | 5 | ll power(ll x,ll n) 6 | { 7 | int ans=1; 8 | while(n){ 9 | if(n&1)ans*=x; 10 | x*=x; 11 | n>>=1; 12 | } 13 | return ans; 14 | } 15 | 16 | int main() 17 | { 18 | int x,n; 19 | cin>>x>>n; 20 | cout< 2 | using namespace std; 3 | typedef long long ll; 4 | 5 | ll pow_mod(ll a,ll b,ll c) 6 | { 7 | ll ans=1; 8 | while(b){ 9 | if(b&1)ans=(ans*a)%c; 10 | a=(a*a)%c; 11 | b>>=1; 12 | } 13 | return ans; 14 | } 15 | 16 | int main() 17 | { 18 | int a,b,n; 19 | while(cin>>a>>b>>n){ 20 | cout< 2 | using namespace std; 3 | 4 | int Rank(char op) 5 | { 6 | if(op == '+' || op == '-') return 1; 7 | if(op == '*' || op == '/') return 2; 8 | else return 0; 9 | } 10 | 11 | bool compare(char a, char b) 12 | { 13 | return Rank(a) > Rank(b); 14 | } 15 | 16 | void caculate(stack &S1, stack &S2) 17 | { 18 | double x = S1.top();S1.pop(); 19 | double y = S1.top();S1.pop(); 20 | switch(S2.top()) { 21 | case '+': S1.push(x + y); break; 22 | case '-': S1.push(y - x); break; 23 | case '*': S1.push(y * x); break; 24 | case '/': S1.push(y / x); break; 25 | } 26 | S2.pop(); 27 | } 28 | 29 | void arrange(char x, stack &S1, stack &S2) 30 | { 31 | if(S2.empty()) S2.push(x); 32 | else { 33 | while(!S2.empty() && compare(x, S2.top()) == 0) caculate(S1, S2); 34 | S2.push(x); 35 | } 36 | } 37 | 38 | int main() 39 | { 40 | int T; 41 | char s[1001]; 42 | stackS1; 43 | stack S2; 44 | cin >> T; 45 | while(T--) { 46 | cin >> s; 47 | int len = strlen(s); 48 | for(int i = 0; i < len; ++i) { 49 | if(isdigit(s[i])) { 50 | double n = atof(&s[i]); 51 | while(i < len && (isdigit(s[i]) || s[i] == '.')) i++; 52 | i--; 53 | S1.push(n); 54 | } 55 | else { 56 | if(s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') arrange(s[i], S1, S2); 57 | else if(s[i] == '(') S2.push(s[i]); 58 | else if(s[i] == ')') { 59 | while(S2.top() != '(') caculate(S1, S2); 60 | S2.pop(); 61 | } 62 | else while(!S2.empty()) caculate(S1, S2); 63 | } 64 | } 65 | if(S1.size() == 1) cout << S1.top() << endl; 66 | S1.pop(); 67 | } 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /数据结构/双端队列:栗酱简单的数据结构.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | dequedq; 6 | int n,m,a,op; 7 | cin>>n>>m; 8 | while(m--){ 9 | cin>>op; 10 | if(op==1){ 11 | cin>>a; 12 | dq.push_front(a); 13 | } 14 | else if(op==2)dq.pop_front(); 15 | else if(op==3){ 16 | cin>>a; 17 | dq.push_back(a); 18 | } 19 | else if(op==4)dq.pop_back(); 20 | else if(op==5)reverse(dq.begin(),dq.end()); 21 | else if(op==6){ 22 | cout< 2 | #include 3 | using namespace std; 4 | 5 | typedef struct LNode { 6 | int coef; //系数 7 | int expon; //指数 8 | struct LNode *next; 9 | }LNode, *Polynomial; 10 | void Attach(int a, int b, Polynomial *rear) 11 | { 12 | Polynomial temp = (Polynomial)malloc(sizeof(LNode)); 13 | temp->coef = a; 14 | temp->expon = b; 15 | temp->next = NULL; 16 | (*rear)->next = temp; 17 | (*rear) = temp; 18 | } 19 | Polynomial PolyAdd(Polynomial p1, Polynomial p2) 20 | { 21 | Polynomial front, rear, temp; 22 | int sum; 23 | front = rear = (Polynomial)malloc(sizeof(LNode)); 24 | while (p1 && p2) { 25 | if (p1->expon > p2->expon) { 26 | Attach(p1->coef, p1->expon, &rear); 27 | p1 = p1->next; 28 | } 29 | else if (p1->expon < p2->expon) { 30 | Attach(p2->coef, p2->expon, &rear); 31 | p2 = p2->next; 32 | } 33 | else { 34 | sum = p1->coef + p2->coef; 35 | if (sum) Attach(sum, p1->expon, &rear); 36 | p1 = p1->next; 37 | p2 = p2->next; 38 | } 39 | } 40 | for (; p1; p1 = p1->next) Attach(p1->coef, p1->expon, &rear); 41 | for (; p2; p2 = p2->next) Attach(p2->coef, p2->expon, &rear); 42 | temp = front; 43 | front = front->next; 44 | free(temp); 45 | return front; 46 | } 47 | void create(Polynomial p) 48 | { 49 | int n, coef, expon; 50 | Polynomial rear = p; 51 | cin >> n; 52 | while (n--) { 53 | cin >> coef >> expon; 54 | Polynomial temp = (Polynomial)malloc(sizeof(LNode)); 55 | temp->coef = coef; temp->expon = expon; temp->next = NULL; 56 | rear->next = temp; 57 | rear = temp; 58 | } 59 | } 60 | 61 | Polynomial polyMutiply(Polynomial p1, Polynomial p2) 62 | { 63 | Polynomial front, rear, temp, P1,P2; 64 | Polynomial answer = NULL; 65 | int sum; 66 | front = rear = (Polynomial)malloc(sizeof(LNode)); 67 | P1 = p1; 68 | while (P1) { 69 | P2 = p2; 70 | front = rear; 71 | while (P2) { 72 | temp = (Polynomial)malloc(sizeof(LNode)); 73 | temp->coef = P1->coef * P2->coef; 74 | temp->expon = P1->expon + P2->expon; 75 | temp->next = NULL; 76 | rear->next = temp; 77 | rear = temp; 78 | P2 = P2->next; 79 | } 80 | answer = PolyAdd(answer, front->next); 81 | P1 = P1->next; 82 | } 83 | return answer; 84 | } 85 | int main() 86 | { 87 | Polynomial p1, p2, p3; 88 | p1 = (Polynomial)malloc(sizeof(LNode)); 89 | p2 = (Polynomial)malloc(sizeof(LNode)); 90 | create(p1); 91 | create(p2); 92 | p1 = p1->next; 93 | p2 = p2->next; 94 | p3 = polyMutiply(p1, p2); 95 | 96 | Polynomial tmp = p3; 97 | while (tmp) { 98 | cout << tmp->coef << " " << tmp->expon << endl; 99 | tmp = tmp->next; 100 | } 101 | 102 | return 0; 103 | } -------------------------------------------------------------------------------- /数据结构/多项式相加.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | typedef struct LNode { 6 | int coef; //系数 7 | int expon; //指数 8 | struct LNode *next; 9 | }LNode, *Polynomial; 10 | void Attach(int a, int b, Polynomial *rear) 11 | { 12 | Polynomial temp = (Polynomial)malloc(sizeof(LNode)); 13 | temp->coef = a; 14 | temp->expon = b; 15 | temp->next = NULL; 16 | (*rear)->next = temp; 17 | (*rear) = temp; 18 | } 19 | Polynomial PolyAdd(Polynomial p1, Polynomial p2) 20 | { 21 | Polynomial front, rear, temp; 22 | int sum; 23 | front = rear = (Polynomial)malloc(sizeof(LNode)); 24 | while (p1 && p2) { 25 | if (p1->expon > p2->expon) { 26 | Attach(p1->coef, p1->expon, &rear); 27 | p1 = p1->next; 28 | } 29 | else if (p1->expon < p2->expon) { 30 | Attach(p2->coef, p2->expon, &rear); 31 | p2 = p2->next; 32 | } 33 | else { 34 | sum = p1->coef + p2->coef; 35 | if (sum) Attach(sum, p1->expon, &rear); 36 | p1 = p1->next; 37 | p2 = p2->next; 38 | } 39 | } 40 | for (; p1; p1 = p1->next) Attach(p1->coef, p1->expon, &rear); 41 | for (; p2; p2 = p2->next) Attach(p2->coef, p2->expon, &rear); 42 | temp = front; 43 | front = front->next; 44 | free(temp); 45 | return front; 46 | } 47 | void create(Polynomial p) 48 | { 49 | int n, coef, expon; 50 | Polynomial rear = p; 51 | cin >> n; 52 | while (n--) { 53 | cin >> coef >> expon; 54 | Polynomial temp = (Polynomial)malloc(sizeof(LNode)); 55 | temp->coef = coef; temp->expon = expon; temp->next = NULL; 56 | rear->next = temp; 57 | rear = temp; 58 | } 59 | } 60 | int main() 61 | { 62 | Polynomial p1, p2, p3; 63 | p1 = (Polynomial)malloc(sizeof(LNode)); 64 | p2 = (Polynomial)malloc(sizeof(LNode)); 65 | create(p1); 66 | create(p2); 67 | p1 = p1->next; 68 | p2 = p2->next; 69 | p3 = PolyAdd(p1, p2); 70 | Polynomial tmp = p3; 71 | while (tmp) { 72 | cout << tmp->coef << " " << tmp->expon << endl; 73 | tmp = tmp->next; 74 | } 75 | 76 | return 0; 77 | } -------------------------------------------------------------------------------- /数据结构/邻接矩阵写法:求树的直径:大臣的旅费.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schrodingercatss/ACM_Coding_Plan/dda8a2d78525740cc49f246aae7cb2c9e40d6caa/数据结构/邻接矩阵写法:求树的直径:大臣的旅费.cpp -------------------------------------------------------------------------------- /数据结构/邻接矩阵第二种写法:求树的直径:大臣的旅费.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schrodingercatss/ACM_Coding_Plan/dda8a2d78525740cc49f246aae7cb2c9e40d6caa/数据结构/邻接矩阵第二种写法:求树的直径:大臣的旅费.cpp -------------------------------------------------------------------------------- /数据结构/邻接表写法:大臣的旅费.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schrodingercatss/ACM_Coding_Plan/dda8a2d78525740cc49f246aae7cb2c9e40d6caa/数据结构/邻接表写法:大臣的旅费.cpp -------------------------------------------------------------------------------- /数论/bzoj1257:余数之和(分块枚举).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schrodingercatss/ACM_Coding_Plan/dda8a2d78525740cc49f246aae7cb2c9e40d6caa/数论/bzoj1257:余数之和(分块枚举).cpp -------------------------------------------------------------------------------- /数论/收敛极限:icpc水题crue.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schrodingercatss/ACM_Coding_Plan/dda8a2d78525740cc49f246aae7cb2c9e40d6caa/数论/收敛极限:icpc水题crue.cpp -------------------------------------------------------------------------------- /最小生成树/hdu1863:畅通工程(kruskal算法).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, m, ans, cnt; 4 | int bcj[105]; 5 | bool vis[105]; 6 | 7 | struct node { 8 | int u, v, w; 9 | inline bool operator < (const node &x) const { 10 | return w < x.w; 11 | } 12 | } edge[105]; 13 | 14 | inline void init() 15 | { 16 | memset(vis, false, sizeof vis); 17 | memset(bcj, -1, sizeof bcj); 18 | } 19 | 20 | int Find(int x) 21 | { 22 | if(bcj[x] < 0) return x; 23 | return bcj[x] = Find(bcj[x]); 24 | } 25 | 26 | void kruskal() 27 | { 28 | ans = cnt = 0; 29 | sort(edge, edge + m); 30 | for(int i = 0; i < m; ++i) { 31 | int u = Find(edge[i].u), v = Find(edge[i].v); 32 | if(u == v) continue; 33 | bcj[v] = u; 34 | ans += edge[i].w; 35 | cnt ++; 36 | if(cnt == n - 1) break; 37 | } 38 | for(int i = 2; i <= n; ++i) { 39 | if(Find(1) != Find(i)) { 40 | puts("?"); 41 | return; 42 | } 43 | } 44 | printf("%d\n", ans); 45 | } 46 | 47 | int main() 48 | { 49 | int a, b, c; 50 | while(cin >> m >> n, m) { 51 | init(); 52 | for(int i = 0; i < m; ++i) { 53 | scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w); 54 | } 55 | kruskal(); 56 | } 57 | return 0; 58 | } -------------------------------------------------------------------------------- /最小生成树/hdu1863:畅通工程(prim算法).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e2; 4 | const int INF = 0x3f3f3f3f; 5 | bool vis[N + 5]; 6 | int dis[N + 5]; 7 | int maze[N + 5][N + 5]; 8 | int n, m, ans; 9 | inline void init() 10 | { 11 | ans = 0; 12 | memset(vis, 0, sizeof vis); 13 | for(int i = 0; i <= n; ++i) 14 | for(int j = 0; j <= n; ++j) 15 | maze[i][j] = maze[j][i] = i == j ? 0 : INF; 16 | } 17 | 18 | void prim() 19 | { 20 | for(int i = 0; i <= n; ++i) dis[i] = maze[1][i]; 21 | dis[1] = 0; 22 | vis[1] = true; 23 | for(int i = 1; i < n; ++i) { 24 | int k = 0; 25 | bool flag = false; 26 | //找到没有使用过的且离当前点边权最小的点 27 | for(int j = 1; j <= n; ++j) 28 | if(!vis[j] && dis[j] < dis[k]) { 29 | k = j; 30 | flag = true; 31 | } 32 | if(!flag) { 33 | puts("?"); 34 | return; 35 | } 36 | vis[k] = true; 37 | ans += dis[k]; 38 | for(int j = 1; j <= n; ++j) { 39 | //如果dis[k] > maze[k][j],则更新生成树到每一个非树顶点的距离(松弛) 40 | if(dis[j] > maze[k][j]) dis[j] = maze[k][j]; 41 | } 42 | } 43 | printf("%d\n", ans); 44 | } 45 | int main() 46 | { 47 | int a, b, c; 48 | while(cin >> m >> n, m) { 49 | init(); 50 | for(int i = 0; i < m; ++i) { 51 | cin >> a >> b >> c; 52 | maze[a][b] = maze[b][a] = c; 53 | } 54 | prim(); 55 | } 56 | return 0; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /最小生成树/洛谷P3366:kruskal算法模板题.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | const int N = 2e5; 8 | typedef pair P; 9 | int bcj[5005]; 10 | int n, m, cnt, ans; 11 | struct node { 12 | int u, v, w; 13 | inline bool operator < (const node &x) const { 14 | return w < x.w; 15 | } 16 | } edge[200005]; 17 | 18 | int Find(int x) 19 | { 20 | if(bcj[x] < 0) return x; 21 | return bcj[x] = Find(bcj[x]); 22 | } 23 | 24 | void kruskal() 25 | { 26 | cnt = ans = 0; 27 | sort(edge, edge + m); 28 | for(int i = 0; i < m; ++i) { 29 | int u = Find(edge[i].u), v = Find(edge[i].v); 30 | if(u == v) continue; 31 | ans += edge[i].w; 32 | bcj[v] = u; 33 | cnt++; 34 | if(cnt == n - 1) break; 35 | } 36 | } 37 | 38 | 39 | 40 | int main() 41 | { 42 | scanf("%d %d", &n, &m); 43 | memset(bcj, -1, sizeof bcj); 44 | for(int i = 0; i < m; ++i) { 45 | scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w); 46 | } 47 | kruskal(); 48 | printf("%d\n", ans); 49 | return 0; 50 | } 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /最小生成树/洛谷P3366:prim算法模板题.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | const int N = 5e3; 8 | const int INF = 0x3f3f3f3f; 9 | bool vis[N + 5]; 10 | int dis[N + 5]; //存储生成树到其他非树节点的距离 11 | int maze[N + 5][N + 5]; 12 | int n, m, ans; 13 | inline void init() 14 | { 15 | ans = 0; 16 | memset(vis, 0, sizeof vis); 17 | for(int i = 0; i <= n; ++i) 18 | for(int j = 0; j <= n; ++j) 19 | maze[i][j] = maze[j][i] = i == j ? 0 : INF; 20 | } 21 | 22 | void prim() 23 | { 24 | for(int i = 0; i <= n; ++i) dis[i] = maze[1][i]; 25 | dis[1] = 0; 26 | vis[1] = true; 27 | for(int i = 1; i < n; ++i) { 28 | int k = 0; 29 | //找到没有使用过的且离当前点边权最小的点 30 | for(int j = 1; j <= n; ++j) 31 | if(!vis[j] && dis[j] < dis[k]) k = j; 32 | vis[k] = true; 33 | ans += dis[k]; 34 | for(int j = 1; j <= n; ++j) { 35 | //如果dis[k] > maze[k][j],则更新生成树到每一个非树顶点的距离(松弛) 36 | if(dis[j] > maze[k][j]) dis[j] = maze[k][j]; 37 | } 38 | } 39 | } 40 | 41 | int main() 42 | { 43 | int x, y, z; 44 | scanf("%d %d", &n, &m); 45 | init(); 46 | while(m--) { 47 | scanf("%d %d %d", &x, &y, &z); 48 | maze[x][y] = maze[y][x] = min(maze[x][y], z); 49 | } 50 | prim(); 51 | printf("%d\n", ans); 52 | return 0; 53 | } -------------------------------------------------------------------------------- /杂项/uva1587:盒子.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ForMyLove return 0 3 | using namespace std; 4 | 5 | struct rec{ 6 | int length; //长 7 | int width; //宽 8 | }arr[6]; 9 | 10 | bool cmp(rec a, rec b) 11 | { 12 | if(a.length == b.length) 13 | return a.width < b.width; 14 | return a.length < b.length; 15 | } 16 | 17 | int main() 18 | { 19 | while(cin>> arr[0].length >> arr[0].width){ 20 | if(arr[0].length > arr[0].width) swap(arr[0].length, arr[0].width); 21 | 22 | for(int i = 1; i < 6; ++i){ 23 | cin>> arr[i].length >> arr[i].width; 24 | if(arr[i].length > arr[i].width) swap(arr[i].length, arr[i].width); 25 | } 26 | sort(arr,arr+6,cmp); //对矩形进行排序 27 | 28 | bool flag = true; 29 | for(int i = 0; i < 6; i += 2) 30 | if(arr[i].length != arr[i+1].length || arr[i].width != arr[i+1].width) flag = false; 31 | if(arr[0].length != arr[2].length || arr[0].width != arr[4].length || arr[2].width != arr[4].width) flag = false; 32 | 33 | if(flag) cout<< "POSSIBLE" < 2 | using namespace std; 3 | int main() 4 | { 5 | int t,n,k; 6 | cin>>t; 7 | while(t--){ 8 | vectorv; 9 | cin>>n; 10 | for(int i=0;i>k; 12 | v.push_back(k); 13 | } 14 | cin>>k; 15 | sort(v.begin(),v.end()); 16 | if(v.size()<=3); 17 | else{ 18 | for(int i=0;iv[i+3])v[i+3]=v[i]+k; 20 | } 21 | } 22 | cout< 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | const int N = 2e5; 8 | typedef pair P; 9 | int bcj[5005]; 10 | int n, m, cnt, ans; 11 | struct node { 12 | int u, v, w; 13 | inline bool operator < (const node &x) const { 14 | return w < x.w; 15 | } 16 | } edge[200005]; 17 | 18 | int Find(int x) 19 | { 20 | if(bcj[x] < 0) return x; 21 | return bcj[x] = Find(bcj[x]); 22 | } 23 | 24 | void kruskal() 25 | { 26 | cnt = ans = 0; 27 | sort(edge, edge + m); 28 | for(int i = 0; i < m; ++i) { 29 | int u = Find(edge[i].u), v = Find(edge[i].v); 30 | if(u == v) continue; 31 | ans += edge[i].w; 32 | bcj[v] = u; 33 | cnt++; 34 | if(cnt == n - 1) break; 35 | } 36 | } 37 | 38 | 39 | 40 | int main() 41 | { 42 | scanf("%d %d", &n, &m); 43 | memset(bcj, -1, sizeof bcj); 44 | for(int i = 0; i < m; ++i) { 45 | scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w); 46 | } 47 | kruskal(); 48 | printf("%d\n", ans); 49 | return 0; 50 | } 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /离散化处理/bzoj1303:中位数图.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schrodingercatss/ACM_Coding_Plan/dda8a2d78525740cc49f246aae7cb2c9e40d6caa/离散化处理/bzoj1303:中位数图.cpp -------------------------------------------------------------------------------- /计算几何/poj2507:计算几何+二分.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schrodingercatss/ACM_Coding_Plan/dda8a2d78525740cc49f246aae7cb2c9e40d6caa/计算几何/poj2507:计算几何+二分.cpp -------------------------------------------------------------------------------- /计算几何/裁缝大师:求园内正多边形的顶点.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schrodingercatss/ACM_Coding_Plan/dda8a2d78525740cc49f246aae7cb2c9e40d6caa/计算几何/裁缝大师:求园内正多边形的顶点.cpp -------------------------------------------------------------------------------- /读入挂/读入挂.cpp: -------------------------------------------------------------------------------- 1 | inline char NC(void) 2 | { 3 | static char buf[100000], *p1 = buf, *p2 = buf; 4 | if (p1 == p2) { 5 | p2 = (p1 = buf) + fread(buf, 1, 100000, stdin); 6 | if (p1 == p2) return EOF; 7 | } 8 | return *p1++; 9 | } 10 | 11 | inline void readInt(int &x) { 12 | static char c; c = NC(); 13 | static int minus; minus = 1; 14 | for (x = 0; !(c >= '0' && c <= '9'); c = NC()) if(c == '-') minus = -1; 15 | for (; c >= '0' && c <= '9'; x = x * 10 + c - '0', c = NC()); x *= minus; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /题解/atcoder beginnner contest 187.md: -------------------------------------------------------------------------------- 1 | ### Problem A Large Digits 2 | 3 | **题目传送门:** https://atcoder.jp/contests/abc187/tasks/abc187_a 4 | 5 | **解题思路:** 6 | 7 | 给你两个数字$A$和$B$, 求其笛卡尔积,并输出较大的那个值。 8 | 9 | 10 | **Code:** 11 | 12 | ```cpp 13 | #include 14 | using namespace std; 15 | int main() 16 | { 17 | string a, b; 18 | cin >> a >> b; 19 | int s1 = 0, s2 = 0; 20 | for(int i = 0; i < 3; ++i) { 21 | s1 += a[i] - '0'; 22 | s2 += b[i] - '0'; 23 | } 24 | cout << max(s1, s2) << endl; 25 | return 0; 26 | } 27 | ``` 28 | 29 | ### Problem B Gentle Pairs 30 | 31 | **题目传送门:** https://atcoder.jp/contests/abc187/tasks/abc187_b 32 | 33 | **解题思路:** 34 | 给你n个点,让你求满足两点间斜率在$[-1, 1]$的直线条数,题目保证不会出现斜率为无穷大的情况。 35 | 36 | 直接for循环遍历求一边即可,如果担心浮点误差可以将不等式:$-1 <=\frac{y2-y1}{x2-x1} <= 1$, 也即不等式$|\frac{y2-y1}{x2-x1}| <= 1$的分母乘过去 37 | 38 | 化成:$|y2-y1| <= |x2-x1|$ 39 | 40 | 41 | **Code:** 42 | 43 | ```cpp 44 | #include 45 | using namespace std; 46 | 47 | int main(){ 48 | int N; 49 | cin >> N; 50 | vector> A(N); 51 | for(auto& [x, y] : A) cin >> x >> y; 52 | int ans = 0; 53 | for(int i = 0; i < N; i++) 54 | for(int j = i + 1; j < N; j++){ 55 | auto [x1, y1] = A[i]; 56 | auto [x2, y2] = A[j]; 57 | if(abs(y1 - y2) <= abs(x1 - x2)) ans++; 58 | } 59 | cout << ans << endl; 60 | } 61 | 62 | ``` 63 | 64 | ### Problem C 1-SAT 65 | 66 | **题目传送门:** https://atcoder.jp/contests/abc187/tasks/abc187_c 67 | 68 | **解题思路:** 69 | 给你N个字符串$s1, s_2 ... s_n$,每个字符串都由小写字母组成,前面有至多1个`!`。 70 | 请你找到任意一个字符串S,使得`!`+S也存在于这个序列,输出S,否则输出`satisfiable`。 71 | 72 | 我们只要使用一个set,存储所有的字符串,然后判断`!` + S是否在set中即可。 73 | 74 | **Code:** 75 | 76 | ```cpp 77 | #include 78 | using namespace std; 79 | typedef long long ll; 80 | 81 | int main() 82 | { 83 | int N; 84 | cin >> N; 85 | vector S(N); 86 | for(auto &s: S) cin >> s; 87 | unordered_set h(S.begin(), S.end()); 88 | for(auto &s: S) { 89 | if(h.count("!" + s)) { 90 | cout << s << endl; 91 | return 0; 92 | } 93 | } 94 | cout << "satisfiable" << endl; 95 | return 0; 96 | } 97 | ``` 98 | 99 | ### Problem D Choose Me 100 | 101 | **题目传送门:** https://atcoder.jp/contests/abc187/tasks/abc187_d 102 | 103 | **解题思路:** 104 | 有N个村庄,每个村庄有$A_i$票投给Aoki,$B_i$票投给takahashi,takahashi可以去任意个村庄演讲,演讲完后,所有的票都会投给它,而没有演讲的村庄准备投给他的票都会作废,现在请问他至少要去多少个村庄演讲,才可以成功当选市长。 105 | 106 | 107 | 观察知,如果takahashi去第i个村庄演讲,那么Aoki减少$A_i$票,takahashi增加$A_i + B_i$票,那么,从总体上来看,相当于takahashi增加了$2*A_i + B_i$票。 108 | 109 | 我们初始设一个票数差X = $-\sum A_i$,每次演讲完后,$X += 2 * A_i + B_i$,当票数差大于0时,即可成功当选市长。 110 | 111 | **注:** 这题容易WA的地方就是不能直接贪心每次取和大的一个村庄,因为可能出现以下的情况: 112 | 113 | 比如: 114 | ``` 115 | 5 2 116 | 4 3 117 | 3 5 118 | ``` 119 | 那么我们按和排序选的是$3 + 5$,则票数差为$2 * 3 + 5 = 11$,而如果选$5 + 2$的话,则票数差为$2 * 5 + 2 = 12$,即按和最大的情况贪心来选择并不能取到最优解。 120 | 121 | **Code:** 122 | 123 | ```cpp 124 | #include 125 | using namespace std; 126 | typedef long long ll; 127 | 128 | int main() 129 | { 130 | int N; 131 | cin >> N; 132 | ll X = 0; 133 | vector vec(N); 134 | for(int i = 0; i < N; ++i) { 135 | ll A, B; 136 | cin >> A >> B; 137 | X -= A; 138 | vec[i] = 2 * A + B; 139 | } 140 | sort(vec.begin(), vec.end()); 141 | ll ans = 0; 142 | while(X <= 0) { 143 | X += vec.back(); 144 | vec.pop_back(); 145 | ans++; 146 | } 147 | cout << ans << endl; 148 | 149 | return 0; 150 | } 151 | ``` 152 | 153 | ### Problem E Through Path 154 | 155 | **题目传送门:** https://atcoder.jp/contests/abc187/tasks/abc187_e 156 | 157 | **解题思路:** 158 | 159 | 不会 160 | 161 | **Code:** 162 | 163 | ```cpp 164 | 165 | ``` 166 | 167 | ### Problem F 168 | 169 | **题目传送门:** https://atcoder.jp/contests/abc187/tasks/abc187_f 170 | 171 | **解题思路:** 172 | 不会 173 | 174 | **Code:** 175 | 176 | ```cpp 177 | 178 | ``` -------------------------------------------------------------------------------- /高精度/uva11809:浮点数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ForMyLove return 0 3 | using namespace std; 4 | typedef long long ll; 5 | double A[20][40]; 6 | ll B[20][40]; 7 | 8 | int main() 9 | { 10 | //打表 11 | for(int m = 0; m <= 9; ++m){ 12 | for(int e = 1; e <= 30; ++e){ 13 | double mt = 1 - pow(2,-1-m); 14 | double ex = pow(2,e) - 1; 15 | double t = log10(mt) + ex * log10(2); 16 | B[m][e] = t; //把浮点数赋值给整型的,浮点数小数部分会自动截断 17 | A[m][e] = pow(10,t-B[m][e]); 18 | } 19 | } 20 | string s; 21 | double a; 22 | ll b; 23 | while(cin>> s && s != "0e0"){ 24 | for(int i = 0; i < s.size(); ++i) 25 | if(s[i] == 'e'){s[i] =' ';break;} 26 | sscanf(s.c_str(),"%lf %lld", &a, &b); 27 | for(int m = 0; m <= 9; ++m){ 28 | for(int e = 1; e <= 30; ++e){ 29 | if(b == B[m][e] && (fabs(a - A[m][e]) < 1e-5)){ 30 | cout<< m << " " << e <