
算法很美
近视未看清
这个作者很懒,什么都没留下…
展开
-
链表成环问题
利用字节对齐判断链表是否有环,主要的思路就是根据字节对齐规则将字节空隙利用起来。利用字节空隙来标记遍历过的节点。#include <stdio.h>//链表节点struct Node{ int value; struct Node *next;};//创建链表struct Node* createNode(int n){ //头节点 struct Node *head = new struct Node; head->value =原创 2021-09-28 11:28:10 · 274 阅读 · 0 评论 -
手写队列、栈
//链表节点struct Node{ int val; struct Node* next;};//队列class queue{private: struct Node* top; //取数据端 struct Node* rear; //放数据端 int count; //元素个数计数器public: queue(){ rear = new struct Node; rear->next = NULL;原创 2021-09-10 16:18:52 · 262 阅读 · 0 评论 -
二叉树的遍历
#include <stdio.h>#include <stdlib.h>#include <stack>using namespace std;struct Node{ int val; struct Node *left; struct Node *right;};//先序递归遍历void fdfs(struct Node *root){ if(root == NULL){ return;原创 2021-09-07 13:57:09 · 250 阅读 · 0 评论 -
跑步锻炼
import datetimestart = datetime.date(2000,1,1)end = datetime.date(2020,10,1)dt = datetime.timedelta(days=1) #时间间隔为一天cnt = 0while start<=end: if start.weekday()==0 or start.day==1: cnt+=2 else: cnt+=1 start+=dtprint(.原创 2021-03-04 21:26:26 · 125 阅读 · 1 评论 -
机器人塔
机器人塔X星球的机器人表演拉拉队有两种服装,A和B。他们这次表演的是搭机器人塔。类似: A B B A B A A A B B B B B A BA B A B B A队内的组塔规则是:A 只能站在 AA 或 BB 的肩上。B 只能站在 AB 或 BA 的肩上。你的任务是帮助拉拉队计算一下,在给定A与B的人数时,可以组成多少种花样的塔。输入一行两个整数 M 和 N,空格分开(0<M,N<500),分别表示A、B的人数,保证人数合理性。要求输出一原创 2020-11-12 22:50:55 · 177 阅读 · 0 评论 -
密文搜索(滚动哈希匹配子串)
标题:密文搜索福尔摩斯从X星收到一份资料,全部是小写字母组成。他的助手提供了另一份资料:许多长度为8的密码列表。福尔摩斯发现,这些密码是被打乱后隐藏在先前那份资料中的。请你编写一个程序,从第一份资料中搜索可能隐藏密码的位置。要考虑密码的所有排列可能性。数据格式:输入第一行:一个字符串s,全部由小写字母组成,长度小于1024*1024紧接着一行是一个整数n,表示以下有n行密码,1<=n<=1000紧接着是n行字符串,都是小写字母组成,长度都为8要求输出:一个整数, 表示每行密码原创 2020-11-12 16:12:11 · 386 阅读 · 0 评论 -
路径计数(回溯法)
【问题描述】从一个5x5 的方格矩阵的左上角出发,沿着方格的边走,满足以下条件的路线有多少种?• 总长度不超过12;• 最后回到左上角;• 路线不自交;• 不走出5x5 的方格矩阵范围之外。#include <iostream>using namespace std;int vis[6][6];int dx[4]={0,1,0,-1};int dy[4]={1,0,-1,0};int cnt = 0;void dfs(int i,int j,int d){原创 2020-11-11 19:37:29 · 292 阅读 · 0 评论 -
质数分解(01背包+dp)
问题描述:将2019 拆分为若干个两两不同的质数之和,一共有多少种不同的方法?注意交换顺序视为同一种方法,例如2 + 2017 = 2019 与2017 + 2 = 2019视为同一种方法。#include <iostream>#include <vector>using namespace std;vector<int> prem; //存放素数long long dp[400][4040]; //dp数组,用于记忆bool ispre(原创 2020-11-11 16:46:19 · 409 阅读 · 0 评论 -
激光样式(一题多解)
【问题描述】x星球的盛大节日为增加气氛,用30台机光器一字排开,向太空中打出光柱。安装调试的时候才发现,不知什么原因,相邻的两台激光器不能同时打开!国王很想知道,在目前这种bug存在的情况下,一共能打出多少种激光效果?显然,如果只有3台机器,一共可以成5种样式,即:1、全都关上(sorry, 此时无声胜有声,这也算一种)2、开一台,共3种3、开两台,只1种但是30台就不好算了,国王只好请你帮忙了。【答案提交】要求提交一个整数,表示30台激光器能形成的样式种数。注意,只提交一个整数,不要原创 2020-11-04 19:33:23 · 360 阅读 · 0 评论 -
发现环(邻接表+DFS)
问题描述:小明的实验室有N台电脑,编号1~N。原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络。在树形网络上,任意两台电脑之间有唯一的路径相连。不过在最近一次维护网络时,管理员误操作使得某两台电脑之间增加了一条数据链接,于是网络中出现了环路。环路上的电脑由于两两之间不再是只有一条路径,使得这些电脑上的数据传输出现了BUG。为了恢复正常传输。小明需要找到所有在环路上的电脑,你能帮助他吗?输入第一行包含一个整数N。以下N行每行两个整数a和b,表示a和b之间有一条数据链接相连。对于30原创 2020-11-03 22:02:50 · 533 阅读 · 0 评论 -
对局匹配(动态规划)
问题描述:小明喜欢在一个围棋网站上找别人在线对弈。这个网站上所有注册用户都有一个积分,代表他的围棋水平。小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起。如果两人分差小于或大于K,系统都不会将他们匹配。现在小明知道这个网站总共有N名用户,以及他们的积分分别是A1, A2, … AN。小明想了解最多可能有多少名用户同时在线寻找对手,但是系统却一场对局都匹配不起来(任意两名用户积分差不等于K)?输入第一行包含两个个整数N和K。第二行包含N个整数A1, A2, … A原创 2020-11-02 21:24:03 · 514 阅读 · 0 评论 -
任意两点最短路径问题(Floyd算法)
该算法实现的主要思路是声明一个路径矩阵和一个距离矩阵,利用动态规划的思想,依次将所有顶点作为中转顶点进行遍历,计算出当前路径距离与上一次的结果进行比较,如果当前路径的距离更小则更新两个矩阵。最后只需要访问矩阵便可以得到结果。#include<iostream>using namespace std;#define INF 10000 //定义无穷大 #define size 1001 //最大数据规模 int path[size][size];//存路劲 int dis[size]原创 2020-08-27 13:35:17 · 1411 阅读 · 1 评论 -
字符串匹配(滚动哈希法)
该方法是对普通哈希法的优化。所谓滚动哈希法就是对原串求哈希值时不再像普通哈希法那样每次都要重新算一遍,而是第一次直接求,之后的哈希值直接用前一次的结果直接算出,这样便可以减少一层循环,大大节约了时间。具体实现的方法就是将上一次的哈希值乘以进制数-上一次开头的字符乘以进制数的m次幂(m为子串的长度)再加上新的字符,依次求出所有的哈希值存入数组中,最后只需遍历哈希值数组即可。具体代码实现:#include<iostream>#include<string>#include<原创 2020-08-26 15:32:56 · 646 阅读 · 0 评论 -
字符串匹配之哈希法
问题描述有时候我们需要检测某一字符串中是否含有某一子串,如果有,出现在哪个位置。大多数人很容易想到的是:利用双指针,一个作用于原串,一个作用于子串,逐个字符进行匹配,如果匹配到了则两个指针同时后移,如果匹配过程中出现匹配失败,则从上一次匹配的初始位置的下一位开始重新匹配,子串的指针重新回到最初的位置。这种方法虽然想法简单,但代码比较繁琐且容易出错。为了在这一问题上进行优化,便有了下面的哈希法。基本思想所谓哈希法,就是对子串取一个哈希值,然后对原串遍历并以子串的长度为单位将原串中每一个字符作为子串开头的原创 2020-08-26 13:07:39 · 360 阅读 · 0 评论 -
通电(Kruskal算法)
【问题描述】2015年,全中国实现了户户通电。作为一名电力建设者,小明正在帮助一带一路上的国家通电。这一次,小明要帮助 n 个村庄通电,其中 1 号村庄正好可以建立一个发电站,所发的电足够所有村庄使用。现在,这 n 个村庄之间都没有电线相连,小明主要要做的是架设电线连接这些村庄,使得所有村庄都直接或间接的与发电站相通。小明测量了所有村庄的位置(坐标)和高度,如果要连接两个村庄,小明需要花费两个村庄之间的坐标距离加上高度差的平方,形式化描述为坐标为 (x_1, y_1) 高度为 h_1 的村庄与坐标为原创 2020-08-26 00:27:06 · 199 阅读 · 0 评论 -
最小生成树之kruskal(克鲁斯卡尔)算法
算法基本思想:在初始状态时隐去图中的所有边,这样图中每个顶点都自成一个连通块。之后执行下面的步骤:(1)对所有的边按边权从小到大进行排序;(2)按边权从小到大测试所有边,如果当前测试边所连接的两个顶点不在同一个连通块中,则把这条测试边加入当前最小生成树中;否则,将边舍弃;(3)执行步骤(2),知道最小生成树中的边数等于总顶点数减1或者测试完所有的边时结束。当结束时,如果最小生成树的边数小于总顶点数减1,则说明该图不连通。并查集(1)如何判断测试边的两个端点是否在不同的连通块中;(2)如何将测试原创 2020-08-25 21:58:00 · 334 阅读 · 0 评论 -
括号匹配问题(递归)
【问题描述】由1对括号,可以组成一种合法括号序列:()。由2对括号,可以组成两种合法括号序列:()()、(())。由4对括号组成的合法括号序列一共有多少种?解题思路:以半边括号作为研究对象,从左往右对2n个半括号(假设有n对括号)进行排列,要使括号有效,则只需满足在排列过程中始终保证已排列的括号中左括号的数目大于等于右括号的数目。由此,便转化为一个递归问题,每一个节点要么选择左括号,要么选择右括号,最后将两种情况的结果加起来。#include<iostream>using name原创 2020-08-19 19:18:55 · 1554 阅读 · 0 评论 -
01背包(dp)
问题描述有n个重量为wi,价值为vi的物品,从这些物品中选出总重量不超过W的物品,求所有方案中价值总和的最大。输入描述第一行输入n。第二行输入质量。第三行输入对应的价值。第四行输入W。1<=n<=100,1<=wi,vi<=100.例如:输入42 1 3 23 2 4 25输出7解法一:递归。代码实现:#include<iost...原创 2020-04-20 11:19:50 · 119 阅读 · 0 评论 -
区间调度问题(贪心)
问题描述有n项工作,每项工作分别在si开始,ti结束。对每项工作,你都可以选择参加或不参加,但选择了参加某项工作就必须至始至终参加全程参与,即参与工作的时间段不能有重叠(即使开始的时间和结束的时间重叠都不行)。问最多可以完成多少项工作?限制条件:1<=n<=1000001<=si<=ti<=109第二行输入n个工作的开始时间。第三行输入n个工作的结束时间。...原创 2020-04-16 20:35:08 · 331 阅读 · 0 评论 -
快速渡河(贪心算法)
问题描述有n的人需要过河,但只有一只船,且一次只能载两个人。每个人都有一个渡河的速度,过河的速度取决于速度最慢的那一个,求所有人过完河的最短时间。输入一个n,表示有n个人。接着输入n个整数表示每个人过河需要的时间。例如:41 2 5 10输出:17思路:有两种可以快速过河的策略,一是由最快的那个人把所有人带过河,二是由最快的和第二快的人先过去,然后最快的那个人再回来,当前最慢的...原创 2020-04-16 16:56:54 · 1313 阅读 · 0 评论 -
硬币支付(贪心算法+递归)
题目:有1,5,10,50,100,500面值的硬币,需要支付A元,最少需要支付多少枚硬币?假设至少存在一种支付方案。输入:每种硬币的数量以及需要支付的钱3 2 1 3 0 2620输出:6思路:每次从面值大的开始支付。代码实现:#include<iostream>#include <algorithm>using namespace std;in...原创 2020-04-16 15:14:30 · 390 阅读 · 0 评论 -
三种方法解决素数环
素数环指的是将从1到n这n个整数围成一个圆环,若其中任意2个相邻的数字相加,结果均为素数,那么这个环就成为素数环。问题描述输入一个n,如果可以生成素数环,输出yes,否则输出no。解法一:纯手工全排列+判断代码实现:#include<iostream>using namespace std;int a[10],n;bool flag=true;void swap(...原创 2020-04-16 12:56:30 · 1318 阅读 · 0 评论 -
部分和问题
问题描述有一个A1……An的序列,判断能否从该序列中选出若干个元素使其和等于k。输入描述:第一行输入一个n,表示有n个元素。第二行输入n个整数。第三行输入一个k。-20<=n<=20.输出描述:如果满足条件输出YES,否则输出NO。解法一:二进制非空子集生成+判断。代码实现:#include<iostream>#include<cmath&g...原创 2020-04-15 19:26:11 · 129 阅读 · 0 评论 -
全排列(递归回溯法)
全排列的本质是调换元素的位置,该法代码简单,但效率并不是很高,当10个数进行全排列时需要耗费的时间并不少。#include<iostream>using namespace std;const int MAX=4; void swap(int arr[],int i,int j) //交换数组中的两个数 { int temp=arr[i]; arr[...原创 2020-04-15 18:17:34 · 323 阅读 · 0 评论 -
非空子集的生成(二进制法)
假如有一个n个元素的集合,那么它的非空子集有2的次方-1个,而一个n位的二进制数除去0刚好可以表示2的n次方-1种状态。刚好可以建立对应的联系,因此只需要检测二进制数所表示的每一种状态1的位置,把对应位置的角标对应的元素添加到集合中即可(一种状态对应一个集合),最后在把集合添加到容器中便可求出所有的非空子集。代码实现:#include<iostream>#include<s...原创 2020-04-15 17:01:19 · 639 阅读 · 0 评论 -
基于队列的基数排序(C++实现)
请先引入头文件.void basesort(int a[],int n)//n个数基数排序{ queue<int>q[10];//定义一个队列数组 int Max=a[0]; for(int i=1;i<n;i++) Max=max(Max,a[i]);//取数数组中的最大值 int len = to_string(Max).l...原创 2020-04-15 12:47:45 · 251 阅读 · 0 评论 -
选择排序(C++实现)
void Xsort(int arr[],int n){ for(int i=0;i<n;i++) { int max=i; for(int j=i+1;j<n;j++) if(arr[j]>arr[max]) max=j; if(i!=max) ...原创 2020-04-15 12:44:03 · 134 阅读 · 0 评论 -
冒泡排序(C++实现)
void Msort(int arr[],int n){ for(int i=n-1;i;i--) for(int j=0;j<i;j++) if(arr[j]<arr[j+1]) { int temp=arr[j]; arr[j]=arr[j+1]...原创 2020-04-15 12:42:52 · 94 阅读 · 0 评论 -
快速排序(C++实现)
void Qsort(int arr[], int low, int high)//从角标为low的元素到角标为high的元素进行从大到小排序{ if(high<=low) return; int i=low; int j=high+1; int key=arr[low];//先把第一个元素当作比较基数 while(true) { ...原创 2020-04-15 12:41:04 · 91 阅读 · 0 评论 -
调整数组-奇数在左偶数在右
问题描述:将一个整型数组的奇数移到最左边,偶数移到最右边,要求时间复杂度为O(n)。解法一:使用辅助空间,遍历目标数组,奇数从辅助数组的前面开始存,偶数从辅助数组的后面开始存。代码实现:#include<iostream>using namespace std;int a[10]={1,5,4,3,8,12,5,7,2,6};int b[10]; //开辟辅助空间...原创 2020-04-15 10:29:24 · 724 阅读 · 0 评论 -
长草(BFS)
问题:小明有一块空地,他将这块空地划分为 n 行 m 列的小块,每行和每列的长度都为 1。小明选了其中的一些小块空地,种上了草,其他小块仍然保持是空地。这些草长得很快,每个月,草都会向外长出一些,如果一个小块种了草,则它将向自己的上、下、左、右四小块空地扩展,这四小块空地都将变为有草的小块。请告诉小明,k 个月后空地上哪些地方有草。【输入格式】输入的第一行包含两个整数 n, m。接下...原创 2020-04-14 23:41:28 · 252 阅读 · 0 评论 -
树状数组求数列的前项和
#include<iostream>#include<cstring>using namespace std;int lowbit(int n){ return n-(n&(n-1));}void uptate(int n,int i,int v,int c[]) //原始数组i位置增加v后,更新c数组{ for(int k=i;...原创 2020-04-14 23:38:06 · 134 阅读 · 0 评论 -
回溯法解数独
问题:输入一个九行九列有解的数独(没填的位置用0表示),输出数独的解。代码实现:#include<cstring>#include <iostream>#include <algorithm>using namespace std;int map[9][9];string ch[9]; //用字符串的形式存输入bool isPlace(int...原创 2020-04-14 23:35:33 · 112 阅读 · 0 评论 -
递归求十进制转二进制
问题:给出一个十进制数输出它的二进制数(没有前导0)。代码实现:#include <iostream>using namespace std;void solve(int n) { if (!n) { return ; } solve(n / 2); cout <<n%2;}int main() { ...原创 2020-04-14 23:28:26 · 234 阅读 · 0 评论 -
递归解决汉诺塔问题
问题:汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。代码实现:#include<iostream>#include<cstdi...原创 2020-04-14 23:18:52 · 241 阅读 · 0 评论 -
BFS解迷宫问题(经典BFS算法)
【问题描述】下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可以通行的地方。010000000100001001110000迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这个它的上、下、左、右四个方向之一。对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫,一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、...原创 2020-04-14 23:12:57 · 2963 阅读 · 4 评论 -
2n皇后问题(经典递归回溯)
问题描述 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。输入格式 输入的第一行为一个整数n,表示棋盘的大小。 接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个...原创 2020-04-14 23:07:06 · 189 阅读 · 0 评论 -
最长连续递增子序列(尺取法)
问题: 例如(1,9,2,5,7,3,4,6,8,0)的最长连续递增子序列为(3,4,6,8).思路: 用两个索引在序列中进行移动,并记录最大的长度和最大长度下的起始索引。需要特别注意的是走在最前面的索引移到了最后并且还是递增的特殊情况。代码实现:#include<iostream>using namespace std;int a[10]={1,9,2,5,7,3,4,...原创 2020-04-14 22:26:40 · 190 阅读 · 0 评论 -
上台阶问题
问题: 楼梯有n阶台阶,一步可以走1个、2个或者3个台阶,一共有多少种上楼梯的方法?代码实现:#include<iostream>using namespace std;int cnt=0;//用于计数void f(int n)//n表示还剩你个台阶需要走{ if(n<0) return; //防止死循环 if(n==0) { ...原创 2020-04-14 21:00:43 · 720 阅读 · 0 评论 -
一条语句判断一个整数是否为2的幂
问题: 输入一个整数,判断这个数是不是2的次方。思路: 判断该整数的二进制是否只有一个1,判断 (n-1)&n 是否等于0即可。如果不能理解请参考我的上一篇文章二进制中1的个数。代码实现:#include<iostream>using namespace std;int main(){ int n; cin>>n; if((n&...原创 2020-04-14 17:16:03 · 133 阅读 · 0 评论