自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(32)
  • 收藏
  • 关注

原创 p2957

分析:题意为求出A串的前缀和B串的后缀或A串的后缀和B串的前缀相等的最长的个数。用map容器把AB的前缀最统计出来,然后再用AB的后缀去匹配就可以了。#include<bits/stdc++.h>using namespace std;int main(){ int ans=INT_MIN; string a,b; map<string,int> m1,m2; cin>>a>>b; //a串的前缀 for(int

2022-02-10 19:37:20 261

原创 p3370

分析:map容器轻松解决。#include<iostream>using namespace std;#include<map>#include<string>int main(){ map<string,int> m; int ans=0; int N; cin>>N; while(N--) { string s; cin>>s; if(m[s]==0) {ans++;m[s]=1;} }

2022-02-10 19:32:01 201

原创 p1102

分析:要求A-B=C有多少总组合,A和B都是要组合的,但是C是固定的,我们可以求出A-C=B有多少种组合。如果A-C存在B,那存在的答案就是A的个数乘B的个数。可以用个map容器来统计。#include<iostream>using namespace std;typedef long long ll;#include<map>int main(){ map<ll,ll>m; ll ans=0; ll num; ll N,C; c

2022-02-10 19:30:41 356

原创 p2580

分析:一道map容器的模板题,map轻松解决。将字符串变为下标,然后桶排。#include<iostream>using namespace std;#include<string>#include<map>int main(){ map<string,int> t; string s; int n,m; cin>>n; while(n--) { cin>>s; t[s]=1; } cin

2022-02-10 19:21:59 85

原创 p3375

算法:kmp分析:kmp是用一个next数组来减少子串比较下标的移动次数。next数组中的内容为这个字符前面最长的相同的前后缀的长度。#include<stdio.h>#include<string.h>char s1[1000010];char s2[1000010];int next[1000010];void get_next(char *s2){ int len=strlen(s2+1); next[1]=0; int j=0; fo

2022-02-10 19:20:06 339

原创 洛谷p2835

分析:我太菜了,这个题写了我三天,我一开始用的并查集模板,交上去18分,然后我调整了一下并的顺序,81分,然后我改不动了,问了群里面的ak大佬,他用了个floyd算法,我就去哔哩哔里大学学习,看算法的动态演示,1倍数都看不懂他在演示什么,然后3分钟的演示我硬是看了十分钟。啊啊啊啊,我做出了的其前提是用了Floyd对数据进行预处理,然后再用并查集。因为这个题的关系是单向的,直接用并查集会导致双向,也就是a给b,c也给b,但是a不会给c。所以普通的并查集不行。#include<std

2022-01-19 12:52:46 576

原创 洛谷p1177

分析:此题说是用快排,但是只要是nlog2(n)的算法都可以过,我比较菜,nlog2(2)的算法只会归并排序,所以我就用归并写了。//归并排序#include<stdio.h>#define ARRLen 200000void sort(int a[],int begin,int mid,int end){ int result[ARRLen]; int i=begin; int j=mid+1; int k=0; while(i<=mid&&amp

2022-01-18 10:42:20 246

原创 洛谷p1111

分析:这个有点图论的味道了,公路是双向的,所以这是个无向图。因为要最早,又要任意两个村庄都通车,所以我们要用到最小生成树的算法,我比较菜,只会克鲁斯卡尔算法。再建立最小生成树的时候就可以统计一下这里面最长的时间是多少,这个就答案。#include<stdio.h>long long N,M;struct road{ long long node1; long long node2; long long time;}roads[100100];long long f

2022-01-18 10:34:24 273

原创 洛谷p2078

分析:啊这,居然让我这个单身汉来配情侣,我可以配-1对吗。认真分析:把小明的朋友和他朋友的朋友和他朋友的朋友的....的朋友的父节点都变成小明,然后统计小明这个集合有多少元素,同理求出小红的子集的元素数,然后求出的数的较小的数就是答案。#include<stdio.h>#include<math.h>int Apy[10010];int Bpy[10010];int find(int x,int *p){ if(p[x]==x) return x; e

2022-01-18 10:26:57 251

原创 洛谷p1455

分析:由此题的标签可以知道,我们需要用到并查集和01背包。因为他要连起来卖,所以我们可以把他所有要连起来的卖的云的价格和价值累计到一朵云上,然后把被累计的云标记成不可用,然后再把可用的云用dp背包做出来,就可以算出最大的价值。#include<stdio.h>#define max(a,b) a>b?a:bstruct thing{ int cost; int value; int parent;}a[50000];int dp[50100];int fin

2022-01-18 10:21:49 187

原创 洛谷p1229

分析:首先第一点,若两颗前后序都相等,那么他们之中的每一个节点最多有一个子树。第二点,中序的不确定是因为不清楚这个点是它的左子树还是右子树。所以我们只要找到前后序中有多少对反过来的字符可以了,然后有n对,就有2的n次方个不同的中序。#include<stdio.h>#include<string.h>#include<math.h>main(){ int ans=0; char a[100000]; char b[100000]; g

2022-01-18 10:16:11 270

原创 洛谷p4913

分析:题意其实没讲清除,因为根节点是1,所以第一个输入的值的根为一,第二输入的值的根为2,第n个输入的值的根为n。(我自己写的时候都没注意,别人问了我特殊样例我才醒悟)。这是这颗树的存储的问题。树的深度,注意,0节点也算节点,它是叶子节点而不是空节点。所以我们可以用前中后遍历中的一种就可以求出树的深度,只需在遍历时传一个num变量,但节点值为0时统计并比较。#include<stdio.h>struct point{ int lc; int rc;};struc

2022-01-18 09:58:23 225

原创 洛谷p1030

分析:这道题的基础是要知道手写后序和中序,求前序。与知道先序和中序求后序的相同点,都是在中序中找到一个点,以此分割左右子树。不同点为,先序的第一个字符必定是根,后序最后一个字符才是根。所以这道题要从后序的最后一个字符开始分割左右子树。#include<stdio.h>#include<string.h>struct tree{ char data; int r; int l;}trees[30];struct tree node[30];cha

2022-01-18 09:49:37 226

原创 洛谷p1551

分析:用parent属组保存双亲,然后判断。#include<stdio.h>int n,m,p;int fa[5010];int find(int x){ if(fa[x]==x){ return x;} else{fa[x]=find(fa[x]);return fa[x];}}void unionn(int x,int y){ int x_fa=find(x); int y_fa=find(y); fa[x_fa]=y_fa;}main(){ sc

2022-01-16 20:12:20 100

原创 洛谷p3367

模板题怎么解释???#include<stdio.h>int N,M;int data[20000];int fa[20000];//模板开始 int unfind(int x){ if(fa[x]==-1)fa[x]=x; if(fa[x]==x) {return x;} else { fa[x]=unfind(fa[x]);//压缩路径 return fa[x]; }}void unionn(int x,int y){ int xx=u

2022-01-16 20:10:25 2875

原创 洛谷p1305

分析:这个题好坑,我一眼一看,以为层次遍历,然后我写完了后发现错了,我一度怀疑这是个啥,然后我下载数据一看,好家伙,这是乱输进来的(除了第一个肯定是头之外)现在开始分析:输入一个字母,然后输入它的左右节点,‘*’为空节点,然后输出这棵树的先序遍历。n是小于26的,所以我们可以用一个大数组来接收,用数组来模拟树。先记录头是哪个字母,然后通过这个字母来找到其它字母就可以了。#include<stdio.h>struct tree{ char data; char lc;

2022-01-16 20:05:11 117

原创 洛谷p1827

分析:通过前序和中序确定一颗树,让后对这棵树进行后续遍历。看看样例:中序:ABEDFCHG先序:CBADEFGH因为先序的第一个必定为根,所以C肯定是根。中序呢,就是把根左边的遍历完,然后根,然后再遍历根右边的。所以在中序中以C为分界点,左边为ABCEDF,根C,右边HG.然后按照先序把点都分好。C 左边:ABEDF 右边:HGB 左边A 右边:EDFA 左右为空,是叶子节点D 左边E 右边FE 叶子节点F 叶子节点G 左边HH叶子节点因此

2022-01-16 19:39:07 354

原创 洛谷p1825

分析:求的是最短时间,我们用bfs。分析题目:本来是个简单的搜索题,但是有个传送门,我们要处理一下,传送门的性质是把点送到相应的点去,所以如果下一个点是传送门,我们可以直接把传送门对面的点放入队列中。#include<stdio.h>struct point { //坐标 int x; int y; //步数 int step;};struct point queue[100000000];//队列 int end;//队尾 int M,N; //地图大小

2022-01-16 19:00:33 186

原创 洛谷p2895

分析:流星有坐标和时间,我们可以把时间作为标志,在地图上先标记出来,如果此时走的时间小于流星落下来的时间,则可以走,否则不能走。注意:当流星砸到重复位置时,以最先砸到的为准。#include<stdio.h>#define max(a,b) a>b?a:bstruct point{int x;int y;int step;};int move[][2]={1,0,-1,0,0,1,0,-1};int map[1000][1000];int book[1000]

2022-01-16 18:54:27 153

原创 洛谷p1101

分析:要找“yizhong”的单词,单词的方向是固定的,所以我们可以先找到y后在往y的8个方向dfs,这样这道题就好写一些。 for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(map[i][j]=='y') { struct point place={i,j}; for(int i=0;i<8;i++) { if(dfs(place,i,1))vis[place.x][place.y

2022-01-15 19:58:43 98

原创 并查集学习总结

这是一个小伙试图学习最短路径,然后被克鲁斯卡尔暴打的故事。然后偷偷打开b站学习了一波并查集。名词解释:合并,查找,集合。

2022-01-15 19:57:07 112

原创 洛谷p2392

分析:本题可以用动态规划dp做,但是因为数据量小,我们这里使用dfs进行穷举。基本思路就是递归加回溯来穷举。我们有四组数据,我们只要能处理一组,剩下的都是照样处理就行了。我们穷举的内容:因为是尽快完事,还能一次做两个。我们可以穷举出怎么样分可以使两组数据的差最小。然后左右脑中大的那个值就是答案;也就是说我们要求分两组数据,两数数据和的差尽量小的情况下他们中大的数据要最小。这样就是最快的了。用一个left和right来分别纪录左右脑耗费的时间。#include&l

2022-01-11 21:47:33 321

原创 洛谷p1135

分析:提取关键字,至少,所以本题用bfs来解。每一个电梯都有可以运动的步长,而且只能是这么长,所以我们要到达目的地要尝试在别的楼层转乘电梯,用bfs来暴力破解,达到楼层后立即返回,这个就不会超时。代码:#include<stdio.h>struct point{ int place; int step;};int book[500];//标记已经走过的路线 int n,aim;//n为楼高,aim为目标楼层 int end=0;//队尾 struct point

2022-01-11 16:38:55 186

原创 洛谷p2036perbet

分析:看似这道题的题目很长,但是总结起来就是求一个最小的子集。所以我们用dfs来把它所有子集列出来,然后找一个最小的就可以了。#include<stdio.h>#include<math.h>#define min(a,b) a<b?a:bint n;unsigned ans=-1;struct food{ int s; int b;}perket[10];void dfs(int num,int ssum,int bsum){ if(nu

2022-01-10 22:52:19 319

原创 洛谷p1596

分析:我们总结题意可知,本题要我们求的是,再方块8格周围连续的区域共有多少个。可以借鉴我们走迷宫的思维,8格中有W即可以走,所以我们可以用dfs来解这道题。走迷宫时,我们为了能有其他的路而用了回溯的思维,但是这里不一样,它连续的W中所以W都是在一个区域,所以不用回溯。#include<stdio.h>struct point{ int x; int y;};int n,m;int move[8][2]={{1,0},{0,1},{-1,0},{0,-1},{1,1

2022-01-10 22:49:31 388

原创 洛谷p1443

分析:本题要求的是到每个点的最短步数,最短这一类的题用宽度搜索算法bfs。因为马可以再八个方向上移动,所以我们的move数组也要做相应的改变。最后要注意用-5%d输出,本题问题就不大了。#include<stdio.h>//#define min(a,b) a<b?a:bstruct point{ int x; int y;};int n,m;int map[500][500];int book[500][500];int move[8][2] = {

2022-01-10 22:43:59 86

原创 洛谷p1162

分析:本题最重要的两点就是反向思维,和边角不会被包围。反向思维为,把所有0变为1,再把未被包围的2变成0;知道这两点后结合dfs算法即可解决.#include<stdio.h>int map[50][50];int book[50][50];int move[4][2]={1,0,-1,0,0,1,0,-1};int n;struct point { int x; int y;};//边角不会被包围,若边角为2则把和他相邻的2变成0 void dfs(st

2022-01-10 22:40:27 164

原创 洛谷p2404 自然数的拆分

分析:从测试数据来看1 1 1 1 1 1 1 总数为7最开始时7个1展开1 1 1 1 1 1 2 最后一个数加1,总数变为8,去掉第7个数1 1 1 1 1 2 第6个数加1,总数为71 1 1 1 1 3 第6个数加1,总数为8,去掉第6个数1 1 1 1 2 2 第5 个数加1,第6个数在第五个数的基础上加0,总数为7推到这里就差不多了。为了避免重复的表达式出现我们使后一个数的起始值为前一个数。因为n小于等于8,所以可以用一个数组把成立的表达式存起来。代码

2022-01-08 20:13:39 306

原创 洛谷P1219 八皇后

分析:行列不能重复,对角线不能重复,行列的判断是很简单的,重点是对角线,如果处理不当就会超时。因为我们用dfs可以从1往n推,所以我们可以控制行内只有一个数据。所以我们要处理的两个问题就是列和对角线不能重复。解法一:列不重复:int findlie(int x,int y){ for(int i=1;i<=n;i++) { if(map[i][y]) return 0; } return 1;}对角线不重复:int finddj(int x,int y){

2022-01-08 14:21:16 92

原创 dfs走迷宫

题目背景给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。题目描述无输入格式第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。输出格式给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方案总数。分析:这是

2022-01-08 13:41:17 427

原创 栈的问题,栈模拟

问题:现在有n个元素分别是1,2,3,...,n,我们想知道通过一个栈,在n次push/pop后,出栈序列可能是什么样的。例如n是5,那么入栈次序就是1,2,3,4,5,如果我们希望出栈次序同样是1,2,3,4,5,那只要每push一个数,就立即pop一个数。如果我们希望出栈次序是3,2,4,5,1,那么我们先让1,2,3入栈,然后pop出来3和2,接着4入栈后马上pop,再就是5入栈后马上pop,最后再把栈里的1pop出。再例如,如果我们希望出栈次序是5,4,1,2,3,这是办不到的,如果要让5最先出栈,

2021-12-16 21:14:02 551

原创 链表排序的归并解法

1.10日总结

2021-12-15 20:18:16 1010 2

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除