![](https://img-blog.csdnimg.cn/20190918140053667.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
刷题
各大算法竞赛试题
Knock man
在校大三学生一枚,软件工程专业 敢于做逆行者,写好每一篇博客,不断提高自己,欢迎交流
展开
-
尼克的任务(dp,逆推)
用vector保存第i分钟开始的任务逆推dpdp[i]表示从i~n分钟拥有的最大空暇时间if(当前时间点没有任务) dp[i]=dp[i+1]+1;else dp[i]=dp[i-t];1.如果当前时间点没有任务,那么肯定是前一时间点的空闲时间加一2.如果当前时间点有任务,那么从这个时间点开始t时间内都是不空闲的#include<cstdio>#include<iostream>#include<vector>using namespace .原创 2020-11-13 11:26:51 · 353 阅读 · 0 评论 -
01迷宫(搜素,联通图)
这道题开始向直接搜素,但是每一次询问都要搜索一次肯定会超时的,可以这么处理用联通图思想,每一次搜索也就是遍历了这一个联通图的全部格子,我们将在一个联通图的格子染上同一种颜色,并且存下这种颜色的联通图的数量,下次如果询问已经被染过色的格子,不需要在去搜索直接输出这个颜色的联通图的数量即可下面代码分别用宽搜和深搜解决#include<iostream>#include<cstdio>#include<queue>#include<cstring>u.原创 2020-10-14 18:05:50 · 282 阅读 · 0 评论 -
一中校运会之百米跑(并查集,map实现)
对于这种字符串产生的关系用map来储存父子关系最为方便#include<iostream>#include<cstdio>#include<map>#include<string>using namespace std;map<string,string> student;int n,m;string find(string s){ if(s==student[s])return s; return student[s]=fi.原创 2020-10-13 18:35:34 · 335 阅读 · 0 评论 -
[USACO3.1]最短网络 Agri-Net(并查集,最小生成树,排序)
巧妙的优化,观察代码两个循环是否可以联合到一个循环处理,还有本题的排序其实可以在输入的时候就直接处理了#include<cstdio>#include<iostream>#include<algorithm>using namespace std;int n;int mp[10000][10000];int parent[1005],rank[1005];struct node{ int x,y,z;}edge[10000];//并查集路径优化 .原创 2020-10-13 18:17:44 · 478 阅读 · 0 评论 -
求细胞数量(联通图,宽搜,深搜)
题目描述一矩形阵列由数字 0 到 9 组成,数字 1 到 9 代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。输入格式第一行两个整数代表矩阵大小 n 和 m。接下来 n 行,每行一个长度为 m 的只含字符 0 到 9 的字符串,代表这个 n×m 的矩阵。输出格式一行一个整数代表细胞个数。输入输出样例输入 #14 100234500067103456050020456006710000000089输出 #14说明/提示数据规模与约原创 2020-10-07 11:20:49 · 366 阅读 · 0 评论 -
村村通(并查集)
题目描述某市调查城镇交通状况,得到现有城镇道路统计表。表中列出了每条道路直接连通的城镇。市政府 “村村通工程” 的目标是使全市任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要相互之间可达即可)。请你计算出最少还需要建设多少条道路?输入格式输入包含若干组测试测试数据,每组测试数据的第一行给出两个用空格隔开的正整数,分别是城镇数目 n 和道路数目 m ;随后的 m 行对应 m 条道路,每行给出一对用空格隔开的正整数,分别是该条道路直接相连的两个城镇的编号。简单起见,城镇从 1 到 n 编号。原创 2020-10-07 11:04:26 · 348 阅读 · 1 评论 -
二叉树(前序遍历,dfs)
题目描述输入一串二叉树,输出其前序遍历。输入格式第一行为二叉树的节点数 n。(1=<n<=26)后面 n 行,每一个字母为节点,后两个字母分别为其左右儿子。空节点用 * 表示输出格式二叉树的前序遍历。输入输出样例输入 #16abcbdicj*d**i**j**输出 #1abdicj直接将字母转化为对应的数字作为下标就可以巧妙解决#include<iostream>#include<map>#include<cstdio&g原创 2020-09-23 11:30:42 · 1154 阅读 · 1 评论 -
二叉树深度(dfs)
注意默认根节点是1,所以从根节点搜索即可#include<iostream>using namespace std;struct node{ int left,right;};node tree[100005];int lea=0;void dfs(int node,int step){ if(node==0){ lea=max(lea,step); return; } dfs(tree[node].left,step+1); dfs(tree[node].rig原创 2020-09-23 10:53:30 · 183 阅读 · 0 评论 -
m图的着色问题
题目背景给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的。图的m着色问题是对于给定图G和m种颜色,找出所有不同的着色法。题目描述对于给定的无向连通图G和m种不同的颜色,编程计算图的所有不同的着色法。输入格式第1行有3个正整数n,k 和m,表示给定的图G有n个顶点和k条边,m种颜色。顶点编号为1,2,…,n。接下来的k行中,每行有2个正整数u,v,表示图G 的一条边(u,v)。输出格式程序原创 2020-08-27 10:33:21 · 1828 阅读 · 0 评论 -
【洛谷】家谱(并查集,map)
题目背景现代的人对于本家族血统越来越感兴趣。题目描述给出充足的父子关系,请你编写程序找到某个人的最早的祖先。输入格式输入由多行组成,首先是一系列有关父子关系的描述,其中每一组父子关系中父亲只有一行,儿子可能有若干行,用 #name 的形式描写一组父子关系中的父亲的名字,用 +name 的形式描写一组父子关系中的儿子的名字;接下来用 ?name 的形式表示要求该人的最早的祖先;最后用单独的一个 $ 表示文件结束。输出格式按照输入文件的要求顺序,求出每一个要找祖先的人的祖先,格式为:本人的名字 +原创 2020-08-26 09:16:10 · 489 阅读 · 0 评论 -
A-B=C问题(map巧妙枚举)
给出一串数以及一个数字 C,要求计算出所有 A−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。输入格式输入共两行。第一行,两个整数 N,C第二行,N 个整数,作为要求处理的那串数。输出格式一行,表示该串数中包含的满足 A−B=C 的数对的个数。输入输出样例输入 #14 11 1 2 3输出 #13**题解:**将A-B=C转化成A=B+C,用map将A的各个数字的个数统计下来,然后枚举B+C(也就是B),将B+C在数组中出现的个数相加就是答案#include<原创 2020-08-24 10:05:45 · 1617 阅读 · 1 评论 -
【洛谷】修复公路(并查集,最小生成树)
题解:从花费时间最少的公路开始修,而且保证不能出现环(并查集性质可以保证,因为环的祖宗相等,所以不会改变任何值),在并查集过程中判断所有点是否连通(即祖宗相同)#include<iostream>#include<algorithm>#include<cstdio>using namespace std;int N,M,parent[10005];struct node{ int x,y,t;};node way[1000005];//排序函数 b.原创 2020-08-23 17:56:03 · 339 阅读 · 0 评论 -
【洛谷】朋友(并查集,关系网)
题目背景小明在A公司工作,小红在B公司工作。题目描述这两个公司的员工有一个特点:一个公司的员工都是同性。A公司有N名员工,其中有P对朋友关系。B公司有M名员工,其中有Q对朋友关系。朋友的朋友一定还是朋友。每对朋友关系用两个整数(Xi,Yi)组成,表示朋友的编号分别为Xi,Yi。男人的编号是正数,女人的编号是负数。小明的编号是1,小红的编号是-1.大家都知道,小明和小红是朋友,那么,请你写一个程序求出两公司之间,通过小明和小红认识的人最多一共能配成多少对情侣。(包括他们自己)输入格式第1行,4原创 2020-08-23 16:54:38 · 561 阅读 · 0 评论 -
【洛谷】搭配购买 背包,并查集捆绑
题解:这里就体现并查集的好处了,买了A物品就要买B物品,同时买了B物品也要买A物品,所以存在一个捆绑关系,不如我们将这种有捆绑款系的物品加入到一个集合中,然后用背包算法解决#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;int n,m,money,w[10005],v[10005],parent[10005],dp[10.原创 2020-08-23 15:51:34 · 213 阅读 · 0 评论 -
【洛谷】五倍经验日(动态规划)
题解:其实是01背包的变种当j>=use[i]时,可以选择用药水打(赢)和不用药水打(输)当i<use[i]时,百分百是输的注意:不管药水够不够在这里都是可以增加价值的#include<bits/stdc++.h>using namespace std;long long n,x,lose[10005],win[10005],use[10005],dp[10005];int main(){ cin>>n>>x; for(int i=0;i&.原创 2020-08-20 10:54:48 · 261 阅读 · 0 评论 -
【洛谷】最大食物链计数(动规记忆化搜索)
题解;这个题和通常搜索不一样,由于搜索的路径有多个起点和多个终点,所以我们需要列举起点,然后搜索到终点(说明此路径满足条件),然后回溯到起点,返回路径数目搜索过程必定会有重复,假如2→3,2→5;在搜索2→3时将到达2的路径情况和记录下来,下次搜索2→5是可以直接使用,无需再搜索下去#include<bits/stdc++.h>using namespace std;int n,m,mp[5005][5005];int sb[5005];//被吃计数int nb[5005];//吃别原创 2020-08-20 09:52:16 · 393 阅读 · 0 评论 -
【洛谷】挖地雷动态规划
题解:动态转移方程:f[i]=max(f[j])+w[i];i:表示当前点j:表示可以到达i点的上一个点w[i]:表示第i点的地雷数f[i]表示起点到i点的爆炸最大地雷数至于记录爆炸顺序可以这样处理q[i]=j(表示第i点是由j点过来的)在动态规划过程中就可以记录,但是输出需要逆向,所以我用了递归逆向输出#include<cstdlib>#include<cstdio>#include<iostream>#include<cmath>..原创 2020-08-20 08:37:34 · 338 阅读 · 0 评论 -
通天之分组背包
题目背景NASA(美国航空航天局)因为航天飞机的隔热瓦等其他安全技术问题一直大伤脑筋,因此在各方压力下终止了航天飞机的历史,但是此类事情会不会在以后发生,谁也无法保证,在遇到这类航天问题时,解决方法也许只能让航天员出仓维修,但是多次的维修会消耗航天员大量的能量,因此NASA便想设计一种食品方案,让体积和承重有限的条件下多装载一些高卡路里的食物.题目描述航天飞机的体积有限,当然如果载过重的物品,燃料会浪费很多钱,每件食品都有各自的体积、质量以及所含卡路里,在告诉你体积和质量的最大值的情况下,请输出能达到原创 2020-07-21 11:08:04 · 305 阅读 · 0 评论 -
多重度背包例题二
此题若使用朴素算法必然超时,所以只能使用二进制优化方法#include<iostream>#include<algorithm>#include<vector>#include<cstdio>using namespace std;int N,V,dp[500005]; struct Good{ int v,w;};int main(){ cin>>N>>V; vector<Good>goods;..原创 2020-07-10 10:36:40 · 195 阅读 · 0 评论 -
多重背包问题例题
#include<iostream>#include<algorithm>using namespace std;const int M=500005;int N,V,v[M],w[M],s[M],dp[M];int main(){ cin>>N>>V; for(int i=1;i<=N;i++){ cin>>v[i]>>w[i]>>s[i]; } //装包(转化为01背包问题) int ..原创 2020-07-10 09:28:28 · 567 阅读 · 0 评论 -
[USACO3.1]总分 Score Inflation(dp,完全背包)
纯完全背包模板#include<iostream>#include<algorithm>#include<string>using namespace std;int m,n,w[50005],c[50005],dp[50005];int main(){ cin>>m>>n; for(int i=1;i<=n;i++){ cin>>c[i]>>w[i]; } for(int i=1;i<..原创 2020-07-10 08:11:35 · 191 阅读 · 0 评论 -
完全背包
【题目描述】设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。【输入】第一行:两个整数,M(背包容量,M≤200)和N(物品数量,N≤30);第2…N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。【输出】仅一行,一个数,表示最大总价值。【输入样例】10 42 13 34 57 9【输出样例】max=12方法一:朴素算法原创 2020-07-09 17:59:07 · 191 阅读 · 0 评论 -
[USACO08DEC]Hay For Sale S(01背包,剪枝)
题目描述农民john面临一个很可怕的事实,因为防范失措他存储的所有稻草给澳大利亚蟑螂吃光了,他将面临没有稻草喂养奶牛的局面。在奶牛断粮之前,john拉着他的马车到农民Don的农场中买一些稻草给奶牛过冬。已知john的马车可以装的下C(1 <= C <=50,000)立方的稻草。农民Don有H(1 <= H <= 5,000)捆体积不同的稻草可供购买,每一捆稻草有它自己的体积(1 <= V_i <= C)。面对这些稻草john认真的计算如何充分利用马车的空间购买尽量多的原创 2020-07-09 08:38:37 · 262 阅读 · 0 评论 -
最大约数和(动态规划,01背包)
解题:处理背包问题,解题的关键在于找到下面四点:1.可供选择的数目n2.背包的大小m3.第i个物体的重量从c[i];4.第i个物体的价值v[i];找到上面四点,解决题目就游刃有余了!!!对于解决本题:可供选择的数目n和还有背包的大小m其实就是S第i个物体的重量=i(也就是数的大小)第i个物体的价值=i的约数和如下:我们列出每个数的约数和可以发现,选取数字4和数字6可以使和最大3+6=9;假如我们选择了数字11,背包大小还剩1,我们得到的价值8是8不是最优解所以综上,本题是.原创 2020-07-07 16:10:11 · 380 阅读 · 0 评论 -
小A点菜(搜索,dp)
方法一:搜索利用搜索进行选择即可,但要防止重复选择#include<cstdio>using namespace std;int N,M,menus[10005],count=0;bool vis[10005];void dfs(int k,int sum,int ar){//ar用于保护不重复选择 if(sum>M){//选菜的价格大于总价格 return; } if(sum==M){//选到价格刚好合适的菜品搭配 count++; return;原创 2020-07-07 07:52:50 · 236 阅读 · 0 评论 -
装箱问题(动态规划法,搜索法)
思路:背包,但是此题背包的体积和价值是同一个东西此题虽然不卡剪枝,但是这里还是用了一下剪枝#include<iostream>#include<algorithm>using namespace std;int dp[30005],v,n,k;int main(){ cin>>v>>n; for(int i=1;i<=n;i++){ cin>>k; for(int j=v;j>=k;j--){ dp[j].原创 2020-07-01 17:28:13 · 911 阅读 · 0 评论 -
开心的金明(动态规划,dp,背包)
思路:动规01背包问题,注意计算价值时有一个价格和重量度的乘积计算方法一:二维背包#include<iostream>#include<string>#include<algorithm>using namespace std;int dp[30][30005];int v[10000],w[100005];int n,m;int main(){ cin>>n>>m; ///输入 for(int i=1;i<=m;.原创 2020-07-01 15:57:34 · 227 阅读 · 0 评论 -
采药(01背包)
解法一:二维数组背包这里注意选择之前需要测一测有没有选择的资格#include<iostream>#include<algorithm>#include<string>using namespace std;int T,M;int f[1005][1005];int t[1005],v[1005];int main(){ cin>>T>>M; for(int i=1;i<=M;i++) cin>>t[i]..原创 2020-06-30 11:06:39 · 511 阅读 · 0 评论 -
排队接水(贪心,稳定排序)
思路:贪心,其实就是将接水的人按时间从小到大排序,并且注意坑点,这里的排序是稳定排序(稳定排序就是若两数相同,按输入顺序进行排序),STL排序函数stable_sort可实现此功能,参考:稳定排序但是我这里是直接手写一个插入排序算法实现(因为插入排序是稳定排序)#include<iostream>#include<cstdio>using namespace std;int n;struct people{ int id; int time;};//插入排序是稳.原创 2020-06-26 11:58:50 · 475 阅读 · 0 评论 -
[USACO1.3]混合牛奶 Mixing Milk(贪心背包问题)
题解:此题为贪心背包问题,先将奶农按价格排序,然后从单价最小的取起,直到将背包装满为止,也就是到满足数量为止#include<iostream>#include<algorithm>using namespace std;struct milker{ int money;//单价 int amount;//产量 };int n,m;void paixu(milker mk[]){ int t; for(int i=0;i<m-1;i++){ for.原创 2020-06-26 11:05:58 · 677 阅读 · 0 评论 -
数列分段Section I(贪心)
题解:简单的贪心,有两种方法,一种是存入数组后再处理,一种是边输入边处理。方法一(存入数组后处理):#include<iostream>#include<cstdio>using namespace std;int array[100005];int main(){ int N,M; cin>>N>>M; //输入数列 for(int i=0;i<N;i++){ cin>>array[i]; } //开始分段.原创 2020-06-26 10:28:57 · 492 阅读 · 0 评论 -
合并果子 / [USACO06NOV] Fence Repair G(贪心,优先队列,multiset)分别实现
题解:此题为贪心思想,实际上也是哈夫曼树的一个构造问题,具体做法如下:首先对果子数目按从小到大顺序进行排序,将第一个果子和第二个果子的数目和计算到第二个果子中,计算体力耗费值,然后利用插入排序思想将第二个果子插入到合适位置(利用此方法可节约排序空间),然后将第二个果子和第三个果子的数目和计算到第三个果子中,重复以上操作,可得最小体力耗费值代码实现:#include<iostream>#include<algorithm>using namespace std;int a.原创 2020-06-24 18:15:14 · 335 阅读 · 0 评论 -
医院设置(树最短路)
思路:利用邻接矩阵储存树,利用Floyd算法更新矩阵,将任意两点之间路径算出来,利用双重循环找出最小值#include<cstdio>int e[105][105];int a[201];int n;int main(){ scanf("%d",&n); //初始化邻接表 for(int i=1;i<=n;i++){ for(int j=1;j&l...原创 2020-04-28 16:46:38 · 235 阅读 · 0 评论 -
最少转机(图的遍历)
题意:小哼和小哈一起去做飞机旅游,他们现在位于a号城市,目标城市是b号城市,可以a号城市没有直达b号城市的航班,不过小哼已经收集了很多的航班信息,现在小哼希望找一种乘坐方式使得转机次数最少,如何解决呢?样例输入:5 7 1 51 21 32 32 43 43 54 5样例输出:2说明:第一行表示有四个数分别表示:第一个数:有n个城市 第二个数:有m条航线 第三个数:起点...原创 2020-04-27 18:12:44 · 475 阅读 · 0 评论 -
城市地图(有向图的遍历)
题意:从1号城市到n号城市有许多种走法,现在给出你每两条联通的城市的公路里程,请你求最短1号城市到n号城市的最短路径(注意,公路是单向的)输入:5 81 2 21 5 102 3 32 5 73 1 43 4 44 5 55 3 3输出:9**描述:**第一行表示有n个城市,m条公路,接下来m行类似a,b,c这样的数据表示a城市可以到b城市,里程为c代码;#inclu...原创 2020-04-27 17:49:27 · 1047 阅读 · 0 评论 -
机器翻译(queue,set)
#include<cstdio> #include<queue>#include<set>using namespace std;int n,m;set<int>Q;queue<int>q;int main(){ int x,ans=0; scanf("%d %d",&m,&n); for(int i...原创 2020-04-17 17:59:50 · 185 阅读 · 0 评论 -
约瑟夫问题(queue)
题解:队列应用裸题#include<cstdio>#include<queue>using namespace std;int n,m;int main(){ queue<int>qu; scanf("%d %d",&n,&m); for(int i=1;i<=n;i++){ qu.push(i);//初始化队列 ...原创 2020-04-17 17:21:42 · 304 阅读 · 0 评论 -
后缀表达式(栈应用模板)
题解:这是一道栈的裸题,依次压栈出栈即可,细节处理在于可能是多位数,所以要进行一个字符串到十进制的转换计算#include<cstdio>#include<stack>#include<string>#include<iostream>using namespace std;stack<int>tk;string s;v...原创 2020-04-17 14:49:46 · 333 阅读 · 0 评论 -
又是毕业季
题解:先搜索找出每一组选择,用gcd着出最大公约数,该代码时间复杂度度过高,日后优化#include<cstdio>int n;int a[10005],gcdn[10005];//gcdn[]储存k=i的最大公约数 int ll[10005];//记录搜索过程 int gcd(int a,int b){ return b==0?a:gcd(b,a%b);}int ...原创 2020-04-17 11:02:07 · 204 阅读 · 0 评论 -
计算分数
题解:此题难度不大,但是时考验做题细心的经典题型,我们只需要循环输入两个数即可,也不需要用到字符串的知识,计算时也不需要考虑正负号,巧妙得用格式化输入输出来处理。需要考虑的点:1.用公约数进行约分时,要借助参数m将值保存,防止影响第二个分式约分2.输出时对分子分母相等的单独讨论3.输出时对分母等于1的单独讨论4.输出时对分子为零的单独讨论5.输出时对分母为负数的单独讨论(按分式的写法...原创 2020-04-17 09:57:22 · 202 阅读 · 0 评论