![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
白书
陈末iiiiiiiiiiii
Retired
展开
-
POJ - 2785 折半枚举 (双向搜索 )
题目 给你4个长度为N的数组,从每个数组中拿出一个数,加起来为0的情况有几种。从不同位置拿出来的就叫不同情况。 题解思路 将问题简化为A + B = -(C+D) ,枚举C+D的所有和进行排序,对于枚举出的A+B二分查找相反值。 时间复杂度化简为N平方log N 当原数组为升序时,upper_bound查找第一个大于值的数,lower_bound查找第一个大于等于的数。作差就是相等的值。 AC代码 #include <iostream> #include <cstdio> #incl原创 2021-08-10 20:42:47 · 110 阅读 · 0 评论 -
POJ - 1222 开关问题 二维
题目 题解思路 按照白书上的思路,我们固定第一行的翻转情况,此时第一行只能由第二行对应列的开关来处理,判断此时上一行的情况来翻转。这样又可以固定第二行,以此类推,当最后一行满足情况的时候一个方案就是正确的,此时取小即可。 固定第一行的情况就用到了二进制枚举,枚举2的N次方,翻还是不翻。 最后时间复杂度为 MN2的N次方 AC代码 #include <iostream> #include <cstdio> #include <cstring> #include <原创 2021-08-10 18:45:29 · 115 阅读 · 0 评论 -
POJ - 3185 反转 开关问题 变式
题目 题目保证有答案 题解思路 这题和POJ - 3276有点小区别导致了,左右方向翻转结果,POJ - 3276保证了连续序列的每个点必须要翻转到,而这题则可以卡一个角落使得只翻转2个。 例如 0 0 1 0 0 0 0 0 0 0 … 从右往左对2翻转,然后对1翻转就解决了。 AC代码 #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include &原创 2021-08-10 15:57:00 · 59 阅读 · 0 评论 -
POJ - 2100 尺取法模板 + 难得一用的vector二维
题目 题解思路 数越往前,需要的数字个数就越多,所以直接从前往后找就行了。 这里用了vector二维存最后的答案。 vector用下标访问的时候,这个元素必须已经存在,所以加入新一维数组时,要定义一个临时的数组,然后push_back进去。 这里也可以优化,只存首尾的数字,在输出的时候再遍历。 AC代码 #include <iostream> #include <cstdio> #include <cstring> #include <queue> #inc原创 2021-08-10 15:16:51 · 79 阅读 · 0 评论 -
POJ - 2739 筛素数 + 尺取法
题目 题解思路 筛出素数数组,然后进行尺取,考虑此时的区间和,当小于时,往前走,大于等于时,将头部收缩。当头部都比n大时,没有往前的必要了。 AC代码 #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <algorithm> #include <map> #include原创 2021-08-10 14:47:52 · 126 阅读 · 0 评论 -
POJ - 3276 反转(开关问题) 枚举 区间处理技巧
题目 题解思路 对于每个区间K,我们从小到大进行枚举。 某个点转奇数次就会改变,偶数次就不会改变。 从1开始遍历,当他为B时,对这个区间进行翻转。这里有个处理技巧。 定义一个滚动的大小为K的区间的翻转次数合为sum。 当某点的翻转只受到之前K-1个和自己的影响。 用sum进行动态更新,a[i]+sum取模判断这点的情况。、 当往前时,前k-1个的最开始那个剔除,加上i本身即可。 AC代码 #include <iostream> #include <cstdio> #include原创 2021-08-08 18:33:09 · 140 阅读 · 0 评论 -
POJ - 3579 二分枚举答案 查找第K大
题目 题解思路 很显然不能直接求出ans数组,先将数组排序,因为是任意差值的绝对值,顺序并不影响,我们对答案进行枚举。ans数组大小为n*(n-1)/2 ,这是可以根据等差数列求和得到的。 答案需要介于符合大于一半的ans数组数到不符合的左右。 设枚举的答案为p 当我们排序完后,很容易枚举出p小于等于那些差值的数量和sum,利用二分函数就可以得到,不论奇数偶数都应该大于ans数组的一半,因为sum包含了p自己的值。 这里还有个有点玄学的问题。 关于二分出来的边界问题,如果验证出来要从下界更新且都为正整数,原创 2021-07-30 16:40:38 · 140 阅读 · 0 评论 -
POJ - 2976 二分枚举答案 最大化平均值
题目 题解思路 白书里的例题,直接对浓度进行枚举。 对每个浓度贪心的判断是否可行。 将方程转变,浓度带入后排序贪心。 对于二分枚举答案,答案需要精度时,我们一般直接让答案二分跑100次,而且边界尽量开大点。 坑点 四舍五入 AC代码 #include <iostream> #include <cstdio> #include <algorithm> using namespace std; long long a[1010],b[1010]; double c[原创 2021-07-30 15:13:34 · 127 阅读 · 0 评论 -
POJ - 1064 二分枚举答案 floor向下取整函数
题目 题解思路 我们可以得到答案的区间 0 到薯条平均长度 。 直接取上界为INF,下界为0进行二分枚举答案。 我们让二分进行100次,可以让答案精确到10的负30次方,所以上界不需要那么精确都行。 输出有点坑,不能四舍五入。 用floor函数先乘100将那两位数提出然后抹去小数位,然后除回去。 AC代码 #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> us原创 2021-07-29 14:30:03 · 118 阅读 · 0 评论 -
POJ - 3421 质因数的排列组合
题目 题解思路 参考大佬的博客 相当于对所有质因子进行排列组合,从1开始往右边乘,这样一定满足从右往左边能整除。 AC代码 #include <iostream> #include <algorithm> #include <cstdio> #include <vector> using namespace std; int vis[1050500]; vector <int> ss; int main () { ios::syn原创 2021-07-28 20:45:26 · 214 阅读 · 0 评论 -
UVA - 10006 快速幂 + 埃式素数筛法
题目 选择一个数a 来满足条件 题解思路 先筛出范围内的所有素数,判断完不是素数后再用快速幂来遍历判断。 坑点 快速幂都要用longlong,别以为有取模就不会爆int,乘的时候照样可能爆了!。 AC代码 #include <iostream> #include <algorithm> #include <cstdio> using namespace std; int vis[80000]; long long kuaisumi(long long di,lo原创 2021-07-28 15:33:00 · 63 阅读 · 0 评论 -
Aizu - 2224 最小生成树变式
题目 有n个点和m条边,每条边有不同的权值,问最少花费多少删除边能使得图中没有圈。 给你点的坐标,自己计算边权。 结果保留3位小数。 题解思路 有位大佬讲的很好大佬的博客 没看懂题目郁闷好久 AC代码 #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; const int maxn = 0x3f3f3f3f ; s原创 2021-07-28 14:29:18 · 106 阅读 · 0 评论 -
Aizu - 2249 在 最短路 基础上 求此时的最小生成树
题目 链接 题解思路 1e5 不存在 负权 锁定 堆优化迪杰斯特拉来处理最短路 生成树就是每个源点被松弛后加入dis数组所组成的,我们只要在松弛后将每个点提供生成树的值代入即可。 不过还是有特殊条件的,当边等于此时的dis值时,我们要选择较小的花费,此时可以松弛也可以不松弛,对最短距离并没有影响。 最后再累加上每个点提供的生成树值即可。 AC代码 #include <iostream> #include <cstdio> #include <algorithm> #in原创 2021-07-27 21:14:50 · 81 阅读 · 0 评论 -
POJ - 3723 最小生成树 最大生成树 求最大优惠值
题目 题解思路 没看清题目,被绕了一下,这里每个人的雇佣费用都是固定的,我们进行要求出能优惠的最大值,根据题目的权值,可以生成一个最大生成树,求出优惠的最大值。 一开始写着写着写成贪心了,忽略了一个人有多个关系的情况,这里用树形的结构就能很好处理了。 AC代码 #include <iostream> #include <algorithm> #include <cstdio> using namespace std; struct node { int x,原创 2021-07-27 17:10:16 · 43 阅读 · 0 评论 -
POJ - 1703 种类并查集 带权并查集
题目 题解思路 因为是提示不同帮派,所以不能用普通的并查集来解决。 注意的 点就是 不同帮派的人的不同帮派就是同一个帮派的。 很容易想到带权并查集来解决,两个状态0 1 代表相同和不同帮派。 这里还有种用朴素并查集实现的种类并查集可以解决这种问题。 开两倍的空间,利用n外的数来附加n内的数的状态。 记 a b c b 相连 我们不直接让 a b 相连 ,让 a和 b+n b和 a+n相连。 c b+n c+n b相连 这时就会有路径压缩使得a和c相连了,这样说明a c有间接的关系。 AC代码 普通并查原创 2021-07-26 17:13:33 · 188 阅读 · 2 评论 -
POJ - 3614 贪心+优先队列优化 贪心策略 物尽其用
题目 题解思路 对于每只鹅,我们尽可能的选择接近的防晒霜。 也就是,让鹅的min和防晒霜升序排列,然后研究每个防晒霜对于鹅,符合最小值的,将其的max值加入队列,从小到大出队。让防晒霜物尽其用。 AC代码 #include <iostream> #include <cstdio> #include <queue> #include <algorithm> using namespace std; struct node { int ma,mi;原创 2021-07-26 14:53:45 · 86 阅读 · 0 评论 -
POJ - 2431贪心 + 优先队列
题目 题解思路 贪心思维 走到不能走时,不断用之前走过的能加油的最大值加,加到加不了还是走不到就是-1。 这样只能判断所有加油站能不能到,这时我们在重点设置一个虚拟加油站来进行上面的操作。 寻找最大量加油的过程用优先队列优化。 边走边把能加油的加上。 AC代码 #include <iostream> #include <cstdio> #include <algorithm> #include <queue> using namespace std; st原创 2021-07-25 18:35:54 · 151 阅读 · 0 评论 -
POJ - 1017 装箱问题(贪心)
题目 题解思路 一开始想用优先队列,结果不知道怎么用上去。 翻了翻大神的题解。 根据3456的个数来判断满足3456至少需要多少箱子,再根据3456空缺的位置,优先填2,因为1最终可以又2分解出来,而1不能分解出2。 最后判断2 1 的个数是否符合条件,不符合就加箱子。 AC代码 #include <iostream> #include <cstdio> #include <algorithm> #include <queue> using namespa原创 2021-07-05 18:04:47 · 126 阅读 · 0 评论 -
POJ - 3190 区间重叠变式 贪心 优先队列
题目 N (1 <= N <= 50,000) 题解思路 将区间按左端点升序排列,然后将一层一层数轴用优先队列来处理,优先队列存储最大右端点和层数的标号(因为我们最后要得到每个区间对应的数轴编号) 因为左端点是升序的,我们让优先队列按右端点的从小到大出队。这样我们能保证,此时的队头数轴是能放的最优数轴。如果还是放不下(重叠了),就新增一个数轴并且编号即可。 AC代码 #include <iostream> #include <cstdio> #include <q原创 2021-07-05 11:01:44 · 110 阅读 · 0 评论 -
POJ - 1328 区间贪心 区间覆盖 挺多细节的
题目 题解思路 首先我们将问题抽象化,利用勾股定理用区间来表示这个岛在岸上大炮能放的位置,我们要做的就是将区间重复的位置找出来,这样我们就可以节省大炮了。 将区间按右端点从大到小排序,按从右到左来遍历处理。 当发现左端点够不到新点的右端点时,我们要新增一门大炮,并将左端点更新为这个新点的左端点。 当发现够得到时,我们就可以节省大炮了,但是我们这门大炮的范围会受到他的影响,有可能这个点的左端点太大了比这个大炮左端点还大时,我们要更新大炮的左端点 当发现某点的高度大于大炮的半径时或者大炮半径为负时,我们要进行原创 2021-07-04 16:17:04 · 100 阅读 · 0 评论 -
POJ - 2376 区间贪心 区间覆盖
题目 题解思路 左端点从小到大,对右端点从大到小,这样保证了初始节点的最优,再根据两个极限情况特判 初始节点的左端点大于1,或者右端点等于t。 这样我们只要在初始节点的基础上上,贪心的 找到左节点符合要求右节点又能最远的情况。 这个贪心策略很容易想到,但是代码实现还是有点难,用了大量标记来解决。 AC代码 #include <iostream> #include <cstdio> #include <algorithm> using namespace std; s原创 2021-07-03 17:44:03 · 138 阅读 · 0 评论 -
POJ - 3069 区间贪心问题
题目 题解思路 参考大佬的文章讲解区间贪心 区间贪心分为三种,此题属于区间覆盖。 我们先将点从小到大排序,如何用一个R的距离来看看能覆盖最远的点,将该点选为标记,然后继续往前覆盖R的距离以内的点。 AC代码 #include <iostream> #include <cstdio> #include <algorithm> using namespace std; int a[1010]; int main () { int r,n; while(~原创 2021-07-03 16:03:48 · 168 阅读 · 0 评论 -
POJ - 3617 贪心 双指针 字符串处理
题目 题解思路 运用双指针,对两边的字符大小做比较,拿小的,当发现他们相等时不能乱拿,要扫一遍看看之后有没有更小的在一边,如何有就拿那一边的。这样就能保证字典序最小。 输出要注意了,80个字符要换行。 AC代码 #include <iostream> #include <cstdio> #include <algorithm> #include <string> using namespace std; string s,t; int check(原创 2021-07-03 09:31:13 · 103 阅读 · 0 评论 -
Aizu - 0525 行列01翻转 二进制枚举
题目 给出n行m列的0、1矩阵,每次操作可以将任意一行或一列反转,即这一行或一列中0变为1,1变为0。问通过任意多次这样的变换,最多可以使矩阵中有多少个1。 N >= 10 M <= 10000 题解思路 行比较少,我们可以枚举行的变换来确定列。 当列的1数目大于一半时不翻转,小于等于时翻转,等于翻转就涉及到奇数取整的问题,例如 1 3 3/2 = 1 .但如果翻转了就是2了,所以等于也要翻转。 这里我用二进制枚举,建议用二进制枚举时数组从0开始,方便后面枚举。 AC代码 #include &原创 2021-07-02 17:40:06 · 359 阅读 · 0 评论 -
POJ - 3187 回溯DFS 或者 全排列next_permutation() 暴力枚举
题目 链接 题解思路 因为数据量小,考虑枚举,可以用DFS枚举全排列,然后判断答案是否正确,因为我们从1开始枚举,本来就是最小字典序,所以有答案就直接return。 也可以用next_permutation(),将前N个数放入数组,然后进行全排列循环,在里面循环判断是否符合答案。 AC代码 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using原创 2021-07-02 16:21:21 · 85 阅读 · 0 评论 -
Aizu - 0121 BFS 反向BFS 利用map进行类似hash的状态压缩 string操作小妙招
题目 题解思路 这题类似八数码,都是转换回一个状态,而且状态受到多影响,不能单纯的BFS操作,于是有了类似打表的方法,反向BFS。 用终点推出能到达的每一个位置,并存起来,这下就是整个图的状态对应数值的情况了,八数码用的康托展开hash出了图的每一个情况对应的数值, 这题数据量小,我们直接用map进行hash。将图一维化变成字符串。利用从没到过的新状态map值等于0来存入数值。 没用过 不太敢用 的小妙招 int pit = s.find('0'); //直接返回第一个0的位置 string原创 2021-06-02 21:24:45 · 94 阅读 · 2 评论 -
POJ - 3009 DFS 回溯 部分点会重复走 不标记
题目 题解思路 因为石头击中砖块后,砖块会消失,破坏了地形,所以我们需要回溯处理。 又因为石头能走的路径受到旁边砖块的影响,所以我们不需要标记(也可以标记在次数内),因为题目有行走的次数限制,而且不多,所以我们只需要剪枝,不需要标记。 此题给我的感觉和那题推箱子有点类似,人的位置会影响箱子能推的位置,所以,给箱子能多走一部分重复的路的权限。 AC代码 #include <iostream> #include <cstring> #include <cstdio> usi原创 2021-06-02 19:41:30 · 90 阅读 · 0 评论 -
POJ - 2386 DFS染色法 模板题
题目 题解思路 对每个目标位置,枚举8个方向。 进行染色处理,遍历全图,未染色的进行DFS操作染色。 AC代码 #include <iostream> #include <queue> #include <cstdio> using namespace std; int dx[8] = {-1,1,0,0,-1,-1,1,1}; int dy[8] = {0,0,-1,1,-1,1,1,-1}; int n,m,ans = 0; bool vis[120][120];原创 2021-06-01 19:29:20 · 79 阅读 · 0 评论 -
POJ - 1852 思维题 开始刷白书 《挑战程序设计》 GOGOGO
题目 题解思路 不能被蚂蚁会掉头误导了,掉头其实可以理解为两方还是往那边走,仔细想想是不是就相当于换了个人还是往那边走!因为是同时出发,所以消耗的时间也是一样的!所以就相当于没有区别的! 这样只需对每个位置的点求一下到两边的时间,每次更新答案即可! int m,n,mans = 0 ,ans = 0; cin>>m>>n; for (int i = 1 ;i <= n ; i++ ) {原创 2021-06-01 18:24:16 · 109 阅读 · 0 评论