ACM总结

排序

1、冒泡排序

时间复杂度为O(n2),1秒内只能对3000个数进行排序。

for(int i=0;ifor(int j=0;j1-i;j++)
    {
        int tmp=buf[j];
        buf[j]=buf[j+1];
        buf[j+1]=tmp;
    }
}
2、快排

sort(buf,buf+n),升序排序,对buf[0]到buf[n-1]排序。
sort(buf,buf+n,cmp),按照cmp规则排序,对buf[0]到buf[n-1]排序。
时间复杂度为O(nlogn)。

bool cmp(int x,int y)
{
    //自定义排序方法
}
sort(buf,buf+n);//buf[0]到buf[n-1]排序
sort(buf,buf+n,cmp);
sort(buf+1,buf+n+1];//buf[1]到buf[n]排序
sort(buf+1,buf+n+1,cmp);
3、题目:

难度0:

  • 给出一串数字,个数为奇数,找出至少出现(n+1)/2次的数,即将所有数从小到大排序,找到第(n+1)/2个数。(杭电1029)
  • 输出若干个数升序排序的结果,最后一个数字后面没有空格。(杭电1040)

难度1:

  • 将一串数字串0051231232050775中的所有的5替换成空格,将被分割出的数字从小到大排序,忽略头部的0,除非这个数字为0,最后一个数字后面没有空格。(杭电1106)
  • 对时针和分针的夹角进行升序排序,输出中位数,用printf输出形如14:05的形式。(杭电1209)
  • 根据每道题的分值,计算学生成绩,对高于分数线的学生进行排序,按成绩降序,考号升序输出。(杭电1236)
  • 将输入的n个数两两相加,并进行降序排序,输出前m大的数,最后一个数字后面没有空格。(杭电1280)
  • 依次输出最大的,最小的,次大的,次小的…数,最后一个数字后面没有空格。(杭电2673)
  • 两条线段,每个坐标上有一个数,找规律,给定坐标输出对应的数。(杭电1391)

搜索

1、DFS、BFS算法讲解

搜索:DFS+BFS

2、题目
  • 存在两个复数X = a + bi,B = c + di,关系为:X = a0 + a1 * B + a2 * B^2 + a3 * B^3 + … + an * B^n,求 { a0, a1, a2, a3, … , an } 并反向输出。(杭电1111 DFS+复数+秦九韶)
  • 输出一个素数环,第一个数字必须为1,存在多个按字典序由小到大输出。每个测试样例后有空行。(杭电1016 DFS+素数环)
  • 给出两个4位数,分别代表起始数字和目标密码,对起始数字的每一位进行加1、减1、交换位置操作,问经过多少步后可以达到目标密码。(杭电1195 BFS)
  • 给出n,m,k,反复对n做+m,-m,*m,mod m的操作,使得 (初始的n+1) mod k = (现在的n) mod k。(杭电1104 BFS+特别注意%与mod运算)

矩阵

一、模板

矩阵加法+乘法+快速幂

二、题目
  • 求 n * n 矩阵的 k 次幂的迹,再模9973的值。(杭电1575 矩阵快速幂)
  • 求矩阵的1~k次幂的和,再模m,最后输出结果矩阵。(杭电1381 矩阵快速幂)

大数

题目
  • 两个大数相加。(杭电1002 两个大数相加)
  • 若干个大数相加。(POJ 1503 若干个大数相加)
  • 大数阶乘。(杭电1042 大数阶乘)

Hash

题目
  • 给出方程ax12+bx22+cx32+dx42=0的系数abcd,求共有多少组正整数解。(杭电1496 hash求方程解)
  • 给定字符串分割为长度为n的子串,每个子串字符种类不超过nc个,求一共可以分割出多少个子串。(杭电1381 hash或map)

并查集

1、模板

并查集

2、题目
  • 判断是不是一棵树。每组输入以0 0 结束,输入以小于0的数结束。(杭电1325 并查集+判断是否为树)
  • 建一个迷宫,任意两点是双向连通的,要求任意两点只能有一条路可走。(杭电1272 并查集+判断是否存在环形区域)
  • 需要修多少条路能让所有的城镇都连通。(杭电1232 并查集+修路让城镇连通)
  • 1认识2,2认识3,4认识5,则123一张桌,45一张桌,问一共需要多少张桌。(杭电1213 并查集+让认识的人一桌)
  • 词语接龙,上一个词的最后一个字母和下一个词的第一个字母要相同。 (杭电1116 并查集+欧拉路+欧拉回路)

最短路径

1、模板

       Floyd+Dijkstra+SPFA

2、算法

(1)Floyd

  • 时间复杂度为O(n3),适用于n<200
  • 权值非负
  • 多源,求任意两点间的最短路径
    • 求最小值时,初始化INF为  0xfffffff
    • 求最大值时,初始化INF为 -0xfffffff
  • 判断两点间是否相连
  • 判断是否存在负环

(2)Dijkstra

  • 时间复杂度为O(n2),适用于n<3000
  • 权值非负
  • 求单源点到其他顶点的最短距离

(3)SPFA

  • 时间复杂度为O(v*e)
  • 权值可正可负,如果为负权值,需要判断是否存在负环
  • 求单源点到其它顶点的最短距离
  • 判断是否存在负环
3、题目

难度1:

  • 输出最短路径,没有就输出-1。(杭电1874 Floyd最短路)
  • 输出最短路径。(杭电2544 Floyd最短路)
  • 汇率转换,判断是否能够获益。需要对输入的字符串进行处理。(杭电1217 Floyd最短路+map对输入字符串处理)
  • 输出最短的时间,没有就输出-1,需要对起点和终点进行比较,需要对输入的字符串进行处理。数据量为10000,dijkstra和Floyd都AC。(杭电2112 Floyd+dijkstra最短路+map对输入字符串处理)
  • 从某点出发,一次只能拖一辆车回来,求拖所有车回来所需最短时间。 (杭电2923 Floyd最短路+map对输入字符串处理+字符判断图连通)
  • 给出街道的连通情况,建图,求最短路,没有就输出Holiday。(杭电2722 Floyd最短路+map对输入字符串处理+字符判断图连通+建图)
  • 有一个正方形湖,里面有鳄鱼,人被困在中心圆形岛,求人跳多少步最短路径是多少才能逃出去。(杭电1245 Floyd最短路+最小步数+根据坐标建图)
  • 自定义旅游,每个城市有不同的兴趣指数,起始城市和终点城市为同一个且兴趣指数为0,在标号大的城市没有飞往标号小的城市的飞机(即单向图),求出最大的兴趣指数并输出路径。(杭电1224 Floyd最长路+输出路径)
  • 求花费最小的最短路径,并输出路径。 (杭电1385 Floyd最短路+最小花费+输出路径)
  • 求花费最小的最短路径。(杭电3790 dijkstra最短路+最小花费)
  • 六度分离问题,每条路径长度均为1,判断最短路径长度是否大于6。(杭电1869 Floyd最短路+输出条件判断)
  • 若干个起始点和若干个终点,求这些最短路中最短的一条,数据量为1000,dijkstra暂时WA。(杭电2066 Floyd求几条最短路中最短的一条)
  • 若干个起始点,一个终点,求这些最短路中最短的一条。(杭电2680 dijkstra求几条最短路中最短的一条)
  • 农场中有若干块地,地中有若干条双向路,若干条时光隧道,过去的时候时间会倒退。判断是否能从某块地出发后又回来,看到了离开之前的自己。(POJ 3259 Floyd+SPFA判断负权环)

难度3:

  • 给出若干对顶点和路径长度,要求路径满足如下条件:A到终点的最短路大于B到终点的最短路,则A到B是连通的,求从1到2的满足上述条件的路径的有多少条。(杭电1142 Floyd最短路+记忆化搜索)

动态规划

1、背包问题+题目

01背包+完全背包+多重背包

  • 有一个存钱罐,已知空罐重量e和满罐重量f,有n种硬币,每一种重量为w,价值为p,用这n种硬币填满存钱罐,求填满存钱罐时,存钱罐最小的价值。(杭电1114 完全背包)
  • 两个人收集石头,按分类(价值)分成6类,并从1到6编号,第i号有ni个,价值为i,问是否能够按照价值将它们均分。(杭电1059 多重背包)
  • 一共有资金n元,市场有m种大米,每种大米价格为p,重量为h,袋数为c,求最多能采购的大米的重量。(杭电2191 多重背包)
  • 一共有n块骨头,背包容量为v,每种骨头有一定的价值value和体积volume,每种骨头只有一块,求背包能装下的最大价值。(杭电2602 01背包)
2、斜率dp+题目

斜率dp

  • 输入一个含有n个数字的序列,连续输出的费用是连续输出的数字的和的平方加上常数m,求费用的最小值。(杭电3507 斜率dp)
  • 有n个点,每个点上有一个数字,点与点之间两两相乘,得到的乘积相加,m个炸弹,炸弹位置不确定,有炸弹相连的两个点均不能与其他点进行乘法运算,求和的最小值。(杭电2829 斜率dp)
  • 有n只奶牛,每只奶牛有有一个满意度,要对这n只奶牛进行分组,每组奶牛数量不少于t,一旦分组,组内所有奶牛的满意度都会变为最小的满意度,求所有组内满意度变化的最小值(杭电3045 斜率dp)
  • 给定一个长度为n的数字序列,求长度大于等于 k 的平均值最大的连续子序列。(杭电2993&&POJ2018 斜率dp)
3、状态压缩dp+题目

状态压缩dp

  • 有n门课,每门课s还有d天要交作业,需要c天做完,晚交一天扣1分,求怎样排列做作业的顺序能使得扣分最少。(杭电1074 交作业+状态压缩)
4、其他公式+题目

错排公式+LIS+LCS+LICS+最大子串和

  • 求两个序列的最长递增公共子序列。(杭电1423 最长递增公共子序列 LICS)
  • 输出最大子串和,并输出子串的起始位置和结束位置。(杭电1003 最大子串和)
  • 贫穷的城市只缺一种资源,富裕的城市只盛产一种资源,贫穷和富裕的城市分别在两条平行线上,在贫穷和富裕的城市间修路,城市编号从左到右依次增大,路不能交叉,求最少修多少条路。(杭电1025 最长上升子序列+二分查找优化)
  • 每个棋子上有一个数,从开始位置开始,一次可以跳若干步,求能够达到的最大的和。(杭电1087 和最大的上升子序列)
  • 输出第n个素因子只为2,3,5,7的数。(杭电1058 输出第n个humble数)
  • 有n种长方体,每种长方体有无限个。用这些长方体堆一个高度最高的塔,要求下面长方体的长和宽大于上面长方体的长宽。(杭电1069 按长宽从大到小往上堆高塔)
  • 有一个n * n的网格,每个洞里藏有0~100块奶酪;仓鼠从(0,0)开始走,每次只能走1~k步;每一次走到的洞里的奶酪都要比上一次多;求仓鼠最多能吃多少块奶酪。(杭电1078 DFS+动态规划)
  • 公司做一个项目,需要m月的时间,每个月需要wnum[i]个人。每个月雇佣人需要hire元,工资为salary元,解雇人需要fire元。求公司完成项目所需的最小费用。(杭电1158 公司雇人)

数据结构

一、二叉树

1、二叉树模板

二叉树 遍历+建树

2、二叉排序树模板

二叉排序树 / 二叉搜索树 / 二叉查找树 遍历+建树

3、题目

二叉树:

  • 给出前序和中序遍历,求后序遍历。(杭电1710)

二叉排序树:

  • 给定序列,建立二叉排序树,输出满足下列要求的序列: 按照该序列建树之后和原树一样,新建立的树字典序最小。(杭电3999 数字建立二叉排序树+先序遍历)
  • 给出序列,建立二叉排序树,判断建的树是否为同一棵树。(杭电3791 数字序列建立二叉排序树+判断两树是否相同)

二、哈夫曼树

1、模板

哈夫曼树代码

2、题目:
  • 给出仅由大写字母和下划线组成的字符串,求按正常编码的编码长度,最小的编码长度,以及他们相除的值,保留一位小数。(杭电1053 哈夫曼树+字符串处理)
  • 将n张扑克牌放到图1所示的空框中,得分为扑克牌点数乘以空框到树根的距离,求最小分数。(POJ 1339 哈夫曼树)
  • 有一块长木头,要锯n-1次,锯成n块,锯多长就花多少钱,求花的最少的钱。(POJ 3253 哈夫曼树)

拓扑排序

1、算法

概念+求法+应用

2、模板

拓扑序列

2、题目
  • QQ群中有很多师徒关系,一个师傅可能有很多徒弟,一个徒弟可能有很多师傅。A是B的师傅,B是C的师傅,可以推出A是C的师傅。但A是B的师傅,B也是A的师傅是不合法的。给出师徒关系,判断是否存在不合法现象。(杭电3342 拓扑排序+判断是否为有向无环图)
  • 有N支队伍进行比赛,比赛结束后,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前,求出队伍排名。(杭电1285 拓扑排序)

计算几何

1、算法

判断线段相交:快速排斥+跨立

2、模板

判断线段相交

3、题目
  • 在平面直角坐标系中,通过P操作加入线段,如果两个线段相交,则认为是一个集合的。Q操作询问当前情况下第k条线段所在的集合里面有几条线段(与线段k相交或间接相交<1相交2,2相交3,则1间接相交3>的线段有几条)。输出后测试用例间要有空行。(杭电1558 求线段相交+并查集求集合内个数)

最小生成树

1、模板

prim+kruskal

2、算法讲解

算法导论prim+kruskal

3、题目
  • 有n个村庄,村庄间已经有若干条路,要继续为村庄建路,使得所有的村庄都能连通,并且总路程最短。(杭电1102 最小生成树+prim)
  • 组建军队,包括n个女孩m个男孩,每雇佣一人需要花费10000元。若女孩x和男孩y有d关系,那么花费10000雇佣了x就可以花费10000-d雇佣y。每个人只能使用一次关系。求最少的花费。(POJ 3723 最大生成树+kuruakal )
  • 给出一个图,判断它的最小生成树是否唯一。(POJ 1679 最小生成树+kruskal+记录边)

注意

  • memset初始化时最好将数组赋值为0x3f3f3f3f,而不是1或0xfffffff
  • scanf,printf 头文件为 #include < cstdio >
  • memset 的头文件为 #include < cstring >
  • map的头文件为 #include < map >
  • 不能以pow作为变量名
  • 数组过大时,不能写在main函数中

输出

  • %02d:输出两位的int型整数,不够两位的前面加0,如14,05。
  • %.2lf:输出小数点后保留两位。
  • 比较字符串的大小:strcmp(x.name,y.name)
                                    值为 0 代表x.name = y.name
                                    值为>0代表x.name > y.name
                                    值为<0代表x.name < y.name

超时

  • cout改成printf,cin改成scanf
  • 数组开的不够大
  • 自己写输入函数 输入外挂

英语单词

odd 奇数    digit 数字    prime 素数    non-negative integer非负整数        
add 加    minus 减    
square 正方形    diameter 直径    diagram环    commas 逗号    
distinct 不同的    discrepancy 差异    peculiar 特殊的    collective 集体的    
indicate 表明    guarantie 保证    correspond 相应的
precede 先于    terminate 结束    
intersection 交叉    disjoint 不相交的    adjacent 相邻的    finite 有限的    
ascending 升序    irreversible 不可逆的    lexicographic字典序    
coordinate 坐标    bidirectional path 双向路径    vertical 纵向    horizontal 横向    clockwisely 顺时针    anticlockwisely 逆时针    reoriented 重定向的
generate 形成    compose 构成    component 成分    comprise 包含    

你可能感兴趣的:(算法模板,ACM)