
算法刷题
yws_2973199368
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
PAT 1048 水题 注意c++的foreach
PAT 1048 水题 注意c++的foreach水题。注意c++的foreach在auto指针下遍历时,每次取出容器中的一个元素加入当前副本中,因此不能直接用当前元素进行更新,如果用auto& 指针则可以修改容器中的元素。代码:#include <iostream>#include <map>using namespace std;int N, M;map<int, int> m;int main(){ cin >> N &原创 2021-05-31 13:56:45 · 274 阅读 · 0 评论 -
PAT 1047 水题
PAT 1047 水题继续水,令人快乐代码:#include <iostream>#include <vector>#include <map>#include <string>#include <algorithm>using namespace std;map<int,vector<string>> m;int N,K;int main(){ cin>>N>>K;原创 2021-05-30 21:24:24 · 114 阅读 · 0 评论 -
PAT 1046 水题
PAT 1046 水题水代码:#include <iostream>#include <map>#include <string.h>#include <algorithm>using namespace std;const int maxn = 100005;int N,M,D[maxn];int main(){ memset(D, 0, sizeof(D)); cin>>N; for(int i原创 2021-05-30 19:10:38 · 117 阅读 · 0 评论 -
PAT 1045 最长不减子序列
PAT 1044 最长不减子序列最长不减子序列的变形,用map将颜色映射到其顺序,对其顺序求最长不减子序列即可。需要注意的是,upper_bound函数的开闭性为左闭右开,自己写的二分一般是左闭右闭。代码:#include <iostream>#include <map>#include <string.h>#include <algorithm>using namespace std;const int maxn = 10005;int原创 2021-05-30 18:43:42 · 129 阅读 · 0 评论 -
leetcode 629 逆序对数组计数 dp
leetcode 629 逆序对数组计数 dp很好的一题dp化简,关键在于想清楚每次新拿出来的元素比已经确定逆序对个数的前面所有元素都大,插在哪个位置就新增了多少逆序数。设dp[i][j]为前i个元素构成的含有j个逆序对的序列个数,那么第i个元素插在前i-1个元素的倒数第m个位置,就会新增m个逆序数,即dp[i][j] = Σ_m = 0~m = min(i-1,j)dp[i-1][j-m],当然这样时间复杂度要到O(nk^2),讨论i和j的大小关系确定求和上界,然后错位相减即可化简递推式,复杂度减小到O原创 2021-05-30 16:17:54 · 188 阅读 · 0 评论 -
HDU 1166 树状数组
HDU 1166 树状数组树状数组是解决区间查询问题的一种数据结构。区间查询最简单的形式就是求一段连续区间的和,这种问题可以用前缀和来解决,建立前缀和数组的时间复杂度为O(n),查询的时间复杂度为O(1)。但是当我们频繁对区间的一些点进行修改时,前缀和数组在每一次修改后的查询前都要更新,每次更新都是O(n),这样假如修改并查询m次,总的时间复杂度就来到了O(mn)。树状数组可以降低复杂度,它的建立时间复杂度为O(nlogn),每次修改的时间复杂度为O(logn),每次查询的时间复杂度也是O(logn原创 2021-05-30 16:17:32 · 172 阅读 · 0 评论 -
PAT 1044 前缀和+二分
PAT 1044 前缀和+二分不错的一道题。连续子串的若干个元素之和可以用一维前缀和来表示,而前缀和构成的数列本身肯定严格单调增,对每个前缀和元素作为开头的所有子串二分即可,复杂度O(nlogn)。代码:#include<iostream>#include<map>using namespace std;const int maxn = 100005;int nums[maxn];map<int,int> res,ans;int min_ = 0x3f原创 2021-05-30 11:43:25 · 159 阅读 · 0 评论 -
leetcode 300 最长上升子序列的长度
leetcode 300 最长上升子序列的长度给定一个整型数据串,求其严格单调递增的最长的子序列长度。两种思路,第一种思路dp,设dp[i]为以第i个数字作为结束元素的子序列的最长的长度,那么这个值只会与其前i-1个元素相关,递推式为:dp[i] = max{dp[k]}+1,1 <= k <= i-1 && nums[k] < nums[i]时间复杂度为O(n^2)代码:class Solution {public: int lengthOfLIS(原创 2021-05-30 10:36:30 · 190 阅读 · 0 评论 -
PAT 1043 分治
PAT 1043 分治简单的分治。代码:#include <iostream>#include <vector>using namespace std;const int maxn = 1005;int N;vector<int> res;int tree[maxn];bool flg1 = true,flg2 = true;void isBST(int left,int right){ if(left > right || !f原创 2021-05-28 21:30:44 · 85 阅读 · 0 评论 -
PAT 1042 水题
PAT 1042 水题水代码:#include <bits/stdc++.h>using namespace std;string s = "SHCDJ";int t;int Shuffling[55];vector<string> deck;vector<string> res;int main(){ cin>>t; deck.push_back("#"); for(int i = 1;i <= 54;原创 2021-05-28 18:46:33 · 176 阅读 · 0 评论 -
PAT 1041 水题
PAT 1041 水题水代码:#include <bits/stdc++.h>using namespace std;map<int,int> m;int N;vector<int> v;int main(){ cin>>N; for(int i = 0;i < N;i++){ int tmp; cin>>tmp; m[tmp]++; v.pu原创 2021-05-28 18:46:12 · 116 阅读 · 0 评论 -
PAT 1040 最长回文串
PAT 1040 最长回文串dp,练手代码:#include <bits/stdc++.h>using namespace std;string s;const int maxn = 1005;int dp[maxn][maxn];int dpf(){ int max = 1; for(int r = 2;r <= s.size();r++){ for(int i = 0;i <= s.size()-r;i++){原创 2021-05-28 18:44:46 · 131 阅读 · 0 评论 -
PAT 1039 水题
PAT 1039 水题太菜了,做做水题找自信。代码:#include <bits/stdc++.h>using namespace std;int N,K;map<string,vector<int>> m;int main(){ cin>>N>>K; for(int i = 0;i < K;i++){ int course,n; cin>>course>&g原创 2021-05-28 18:44:11 · 113 阅读 · 0 评论 -
PAT 1038 贪心
PAT 1038 贪心题目分析:贪心,每次选取能使最终的字符串字典序最小的元素。这个操作可以借由sort函数的cmp来确定。sort函数对于各种满足偏序关系的元素都可以进行排序,cmp函数给出这个偏序关系即可。在这个问题中,所有的元素顺序也有一个偏序关系:任意两个相邻元素互换位置,都会使得最终的字符串变大。证明:a,b,c三个元素相邻并满足偏序关系,那么a与b互换,b,a,c三个元素构成的字符串大于原来的字符串;再将a与c互换。。。几天后发现证不出来。。。这题的关键就在于证明这个偏序关系,这里原创 2021-05-28 18:43:34 · 109 阅读 · 0 评论 -
PAT 1037 贪心
PAT 1037 贪心贪心水题,结论很好证明。代码:#include <iostream>#include <vector>#include <algorithm>using namespace std;int n1,n2;vector<int> v1,v2,v3,v4;bool cmp(const int &a, const int &b){ return a > b;}int main(){原创 2021-05-19 17:19:11 · 129 阅读 · 0 评论 -
PAT 1036 水题
PAT 1036 水题比上题海水。。代码:#include <iostream>#include <string>#include <algorithm>#include <vector>using namespace std;struct student{ string name; string gender; string id; int grade; bool operator < (con原创 2021-05-19 16:38:03 · 82 阅读 · 0 评论 -
PAT 1035 水题
PAT 1035 水题水代码:#include <iostream>#include <map>#include <string>#include <vector>using namespace std;int N;map<string,string> m;vector<string> v;int main(){ cin>>N; for(int i = 0;i < N;i++){原创 2021-05-19 16:19:20 · 143 阅读 · 0 评论 -
PAT 1034 无向图dfs
PAT 1034 无向图dfs水题,虽然想了半天。。输出要按照字典序排序,第一次忘了导致测试点2没过。代码:#include <iostream>#include <map>#include <string>#include <set>#include <vector>#include <algorithm>using namespace std;map<string,int> w;map<s原创 2021-05-18 21:31:18 · 100 阅读 · 0 评论 -
PAT 1033 贪心
PAT 1033 贪心题目分析:一道不错的贪心题。首先看到这个题,我考虑的是区间dp,设dp[i][j]为i点到j点的最少话费,那么如何分解这个问题呢?我初步想的是寻找i到j之间的价格最低的站点,花费最少的钱到达那里,然后加满油,即类似dp[i][j]=dp[i][minst(i,j)]+dp[minst(i,j)][j]。但是这个思路是非常不完善的,dp[i][j]在出发时是不一定加满油的,在划分后的后半段出发时也不一定是加满的,这个加的量多少是无法确定的;此外没有考虑油箱的容量,也不知道某个点是否原创 2021-05-18 20:04:16 · 214 阅读 · 0 评论 -
PAT 1032 合并链表的首个相同元素
PAT 1032 合并链表的首个相同元素题目分析:本题虽然题目中用的suffix,但是实际上是只要有相同的段,该段就会合并为同一个链表,因此本题实际上是求一个合并链表的 首个公共元素。在建立链表时,可以比较轻松地统计合并点(即每个公共段的第一个公共点),但是第一个公共点不一定是合并点,还有可能是两个链表中的一个开始结点,这样讨论起来是比较麻烦的。实际上可以直接先从一个链表的开始结点开始遍历,对遍历过的每个结点都进行标记,完成后再从另一个链表的开始结点遍历,遇到的第一个已标记结点就是我们要求的首个相同原创 2021-05-17 17:36:49 · 138 阅读 · 0 评论 -
POJ 1251 最小生成树——kruskal与prim
POJ 1251 最小生成树——kruskal与prim最小生成树裸题,复习用。代码#include <iostream>#include <vector>#include <queue>#include <string.h>using namespace std;const int maxn = 100;struct Edge{ int u,v,w; bool operator < (const Edge &原创 2021-04-14 23:21:34 · 102 阅读 · 0 评论 -
leetcode 95 不同的二叉搜索树 II
leetcode 95 不同的二叉搜索树 II记忆化搜索,同上题。代码class Solution { vector<TreeNode*> backup[10][10];public: vector<TreeNode*> backTrack(int l,int r) { vector<TreeNode*> res; if(l == r){ res.push_back(new TreeNode(原创 2021-04-12 19:20:50 · 73 阅读 · 0 评论 -
leetcode 96 不同的二叉搜索树
leetcode 96 不同的二叉搜索树不同的二叉搜索树在前一博客中已经讨论。代码class Solution { int G[100000]; // 记忆化搜索 int memorySearch(int pos){ if(pos == 0){ return 1; } if(G[pos] != -1){ return G[pos]; }else{原创 2021-04-12 19:20:15 · 89 阅读 · 0 评论 -
POJ 1521 Huffman树
POJ 1521 Huffman树本题给出一个字符串,求其Huffman编码的长度。我们可以统计每个字符出现的次数作为该字符的权重,那么编码总长度就等于外部带权路径长度。进一步地,有结论:Huffman树的外部带权路径长度等于除根结点外的所有结点的权值之和(暂时还没想清楚为什么),因此不需建树,统计所有结点权重即可。输入仅有一个字符需要特判。poj不支持c++11,auto不可用。代码:#include <iostream>#include <map>#include原创 2021-04-03 17:14:06 · 687 阅读 · 0 评论 -
PAT 1031
PAT 1031水题,虽然题目中的那个公式还是没看懂,不过大概意思应该就是n2>=n1。代码:#include <iostream>using namespace std;int main(){ string in; cin>>in; int n = (int) in.size(); int n1 = (n+2)/3; int n2 = n+2-2*n1; for(int i = 1;i <原创 2021-04-01 10:39:22 · 81 阅读 · 0 评论 -
PAT 1030 g++与clang++
PAT 1030 g++与clang++虽然是个dijkstra的水题,但是还是有挺多离谱的地方。首先INF的定义,实际上是0x3f3f3f3f,之前一直写成0x3f3f3f。。。这样在memset的时候就可以直接对每个字节都赋值0x3f即可。再次就是编译器的问题,不知道为啥我的代码很多在g++上都有问题,clang就ok,老是过不了的同学可以试试换个编译器。代码:#include <iostream>#include <string.h>using namespac原创 2021-03-25 21:42:40 · 1156 阅读 · 0 评论 -
PAT 1029
PAT 1029水题again代码:#include <cstdio>using namespace std;const int maxn = 200050;int num1[maxn],num2[maxn];int main(){ scanf("%d",&num1[0]); for(int i = 1;i <= num1[0];i++){ scanf("%d",&num1[i]); } sc原创 2021-03-24 17:21:34 · 81 阅读 · 0 评论 -
PAT 1028
PAT 1028水题使人快乐。两个知识点:c++字符串字典序比较:string s1 = "12sdjsadj";string s2 = "r26retywrewt";s1.compare(s2);若s1的字典序大于s2,则返回正数,若小于,则返回负数,相等则返回0。这一题用cincout会卡最后一个测试点,改成scanfprintf就可以了。printfc++里的string还是%s,但是需要将string调用.c_str()变成c语言字符串。代码:#include <ios原创 2021-03-23 19:09:32 · 141 阅读 · 0 评论 -
PAT 1027
PAT 1027水题代码:#include <iostream>using namespace std;int r,g,b;char radix[] = "0123456789ABC";int main(){ cin>>r>>g>>b; int r1,r2,g1,g2,b1,b2; r2 = r%13; r /= 13; r1 = r%13; g2 = g%13; g /=原创 2021-03-22 16:30:38 · 110 阅读 · 0 评论 -
PAT 1026 模拟
PAT 1026 模拟模拟。有两点很恶心:来的人不是选最早完成的那一桌,而是假如有多桌空闲,选当前已经完成的一桌中编号最小的一桌,假如有一桌空闲,那就是这一桌,假如无桌空闲,那就是最快完成的那桌。vip在有vip空桌时会先去vip空桌,也是优先编号小的。因此要再分析分类。这是第一次写的代码,过了前面几个点。后面有时间再看,现在没心情。#include <iostream>#include <string.h>#include <string>#in原创 2021-03-22 16:29:59 · 76 阅读 · 0 评论 -
旧题新做 leetcode 8 字符串处理 自动机
旧题新做 leetcode 8 字符串处理 自动机当时在做的时候自动机还不熟悉,现在学了编译原理,最近又刚好复习字符串,于是拿出来再做一次。知识回顾:自动机的建立、化简以及与正则表达式的关系这里不再赘述(其实是因为我还没复习),现在只讨论自动机的代码实现。一般而言(PPT上的),自动机有三种实现方式。最朴素的一种就是按照自动机的内容翻译成代码,代码执行到哪,自动机的状态就到了哪,这种显然不太好,太暴力了。考虑通用性,就有了其它的两种方法,第一种是用switch语句反映状态的转换,第一层switc原创 2021-03-21 17:51:07 · 117 阅读 · 0 评论 -
PAT 1093 字符串 动态规划
PAT 1093 字符串 动态规划字符串匹配问题,可以用dp做。f[i][j]为输入序列的前i个字符作为输入,匹配模式串的前j个字符,可以匹配的数量。那么其实只有两种情况,第一种,第i个字符没有被选中匹配,也就是说第i个字符不匹配,那么前i-1个字符的不同匹配数量就是前i个字符的匹配数量;假如第i个字符匹配了模式串中的第j个字符,那么除了前i-1个字符的不同匹配数量,还要再加上前i-1个字符匹配模式串中的前j-1个字符的不同匹配数量,递推公式如下:f[i][j] = f[i-1][j] + f[i-原创 2021-03-21 15:22:08 · 131 阅读 · 2 评论 -
PAT 1025
PAT 1025继续水题。#include <iostream>#include <vector>#include <algorithm>#include <iomanip>using namespace std;struct student{ long long id; int score; int rank; int finalRank; int location; student(long原创 2021-03-20 15:32:18 · 89 阅读 · 0 评论 -
PAT 1022 模拟检索
PAT 1022 模拟检索问题归结为给你一堆结构体,现在我要任给一个属性,返回所有满足该属性的结构体。用map可以快速实现。每个结构体给一个独一无二的id,针对结构体的每个属性创建一个map,然后在读取结构体的时候,按照对应属性的值作为key创建或者更新map(map的value就是属性和该属性值相等的结构体id的集合),这样就按照检索条件完成了各个结构体的归类。c++sort可以对字符串排序,按照字典序。代码:#include <iostream>#include <map&原创 2021-03-20 15:31:45 · 74 阅读 · 0 评论 -
PAT 1024
PAT 1024水题代码:#include <iostream>#include <string>#include <string.h>#include <algorithm>using namespace std;const int maxn = 1000;int num1[maxn],num2[maxn],K;int main(){ memset(num1, 0, sizeof(num1)); memset(nu原创 2021-03-19 16:55:21 · 91 阅读 · 0 评论 -
PAT 1023
PAT 1023水题。注意迭代器end()-1才是最后一个元素,end()是结束符。此外c++最大长度unsigned long long20位,不够本题的数据范围。代码:#include <iostream>#include <vector>#include <string>#include <algorithm>using namespace std;vector<int> in;vector<int> back原创 2021-03-19 13:30:01 · 87 阅读 · 0 评论 -
leetcode124 分治
leetcode124 分治原问题:某个树的最长路径原问题变形:某个树的最大深度,即求左右子树的最大深度子问题:求左右子树的左右子树最大深度最小子问题:空子树的左右子树最大深度子问题合并为父问题:左右子树中最大的那个+根问题变形转化为原问题:左右子树相加+根,合并的同时顺便记录一下,最后所有的子问题中的最大的即为最优解。代码:class Solution { int res = Integer.MIN_VALUE; int backTrack(TreeNode root){原创 2021-03-18 22:18:38 · 103 阅读 · 0 评论 -
PAT 1021 树的最深根
PAT 1021 树的最深根题目分析:关键在于搞清楚一个基本情况:随便选一个节点作为根节点,其各个子树的深度中最大的两个就组成了这个树的最大深度。因此我们最简单的思路就是对树的每个子树进行一次求深度操作,同时记录最深根,然后找最深的两个子树就可以了。这样至少要对所有子树各进行一次操作。可以更加简洁,我们先对整个树进行一次求深度操作,这个时候我们求出来的所有最深点所在的子树都被遍历完了。假如这些点分别属于不同的子树,那么肯定就已经确定了所有的点;假如属于同一子树,我们还要在除了这个子树之外的其它原创 2021-03-18 21:26:57 · 151 阅读 · 0 评论 -
PAT 1020 1119 洛谷1229 二叉树的遍历、递归与分治
PAT 1020 1119 洛谷1229 二叉树的遍历、递归与分治知识复习先说结论根据前序中序可以唯一确定后序或者层序根据后序中序可以唯一确定前序或者层序当二叉树的每个节点都不会只有一个孩子时,根据前序后序可以唯一确定中序或者层序上述确定过程不需要实际建树二叉树的三种遍历首先二叉树的前中后序遍历,分别是“根左右”,“左根右”和“左右根”,这一点是最基础的。但是这里的左右,不仅指的是左孩子和右孩子,还指的是左子树和右子树,它们在根节点确定的时候是集中在一起的,例如:前序:(根)[左子树][右原创 2021-03-17 21:39:06 · 373 阅读 · 0 评论 -
PAT 1019
PAT 1019水题。代码:#include <iostream>#include <string.h>#include <algorithm>using namespace std;int N,b;const int maxn = 1005;int num1[maxn],num2[maxn];int main(){ cin>>N>>b; int i = 0; while(N!=0){原创 2021-03-10 20:07:10 · 96 阅读 · 0 评论