随笔分类 -  DFS-深度优先搜索

很实用的一种暴力方式,当然剪枝在这里很值得一学。
摘要:大d的考题题意:给定一个N*N的矩阵,里面放置1,2,3...N*N这N*N个数,要求是第i个数的行和第i-1个数的列必须相同。问1所在的行的和值与N*N所在列的和值之差最小是多少。解法:通过dfs搜索得到1,2,3,4对应的解分别为0,2,6,12,当N=5的时数据规模已经庞大到无法在有限时间内得到结果了,根据这几组结果推断结果为ans = (N-1)*(N)。提交AC。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#include & 阅读全文
posted @ 2013-03-24 17:04 沐阳 阅读(615) 评论(0) 推荐(0) 编辑
摘要:题意:完全符合树的重心:即找到一个点,其所有的子树中最大的子树节点最少.代码如下:#include <cstdlib>#include <cstring>#include <cstdio> #include <iostream>#include <algorithm>#define MAXN 20000using namespace std;//说白了这一题就是求一棵树的重心 int N, idx; // 说明有N个节点//由于节点较多,且数为稀疏图,因此采用邻接表的形式来存储struct Node { int x, next, cn 阅读全文
posted @ 2013-01-06 22:39 沐阳 阅读(835) 评论(0) 推荐(0) 编辑
摘要:这题的想法就是直接枚举1-m每一个数的数量,先给这n个数全排列,然后除以相同的数的阶乘就可以了。枚举的方法就是dfs了。这里分了两步来完成这个任务,首先找出前k个数的组合,然后再进行任意的组合。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <iostream>using namespace std;// 对于一个给定的m面色子,我们抛掷n次,前k大的数相加为p // 错误的思路为枚举最大的k个数,然后再将剩下的n-k个小于// 前k个数中最小的数进行排列组合/ 阅读全文
posted @ 2012-12-09 20:39 沐阳 阅读(261) 评论(0) 推荐(0) 编辑
摘要:题意:给定一个数独的题目,0代表这个点的值未确定,现在要求填写数字进去且满足:1.每一行必须是1-9的集合2.每一列必须是1-9的集合3.每一个子矩阵内必须是1-9的集合由于给定的约束条件比较多,因此直接dfs即可。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;char G[15][15];int r[15][15], c[15][15], f[15][15];// G用来保留整个图,R用来说明某一 阅读全文
posted @ 2012-11-20 17:35 沐阳 阅读(244) 评论(0) 推荐(0) 编辑
摘要:给定一些关系,求这样的一个划分,满足以下几点:1、每个组合至少有一个成员;2、每个人只能属于一个组;2、每个组内的成员必须相互认识;3、两个组的成员个数要尽可能的接近。首先由必须两两认识我们可以将有向图转化为无向图,之后,我们如果直接对这个图求连通分量的话,有以下结论,如果连通分量的个数为2的话,那么直接可以划分了,如果超过两个的话那么肯定就是没有结果,也就是无法进行分组。最难处理的就是所有点的连通的话,那么如何去做一个划分呢,这个就和割点有关系了,分离一个割点会产生多个连通分量,这要必须保证那些多出来的要再同一个集合内,这样这个问题就很复杂了。简单的做法是建立一个反图,再对这个反图求一次连通 阅读全文
posted @ 2012-09-24 22:29 沐阳 阅读(507) 评论(0) 推荐(0) 编辑
摘要:给定一系列树形关系用来描述整个公司的人员关系,现在问给定的这些关系是否存在矛盾的地方。比赛的时候写搓了,对于每一个点都去考虑的左右区间,其实这样做是不太好的,因为每次从员工推到boss,其实boss的工资是灵活变动的,也就是说只要boss工资的右区间减去所有孩子的左区间后还要至少留下单位1的工资来满足boss,所以只要计算一个区间关系即可,或者说,右区间是与孩子的右区间没有关系的。代码如下:#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#includ 阅读全文
posted @ 2012-09-10 22:01 沐阳 阅读(328) 评论(0) 推荐(0) 编辑
摘要:该题与上题相比增加了多种分法,而不只是四条边,问题是最多能够分成多少条边。上题代码其实错了(已改),但是也过了,这题改的还纠结。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int N, seq[100], mode, use[100], flag;void dfs(int cap, int last, int num){ if (num == N) { flag = 1; return; } if 阅读全文
posted @ 2012-07-25 02:47 沐阳 阅读(320) 评论(0) 推荐(0) 编辑
摘要:该题问给定的棍子能否组成一个正方形。首先我们要判定是否总长度是4的倍数,然后再决定是否存在某条边大于组合边长。搜索的过程中也是可以进行剪枝了。首先将边排序,我们可以假定所有的组合边由大小递减的边组成,那么我们在搜索的时候就不用再往前找边了。其次我们可以确定任何一条边都一定在一条组合边中,那么当我们以任意一条边开搜的情况下无解的话,那么我们就可以直接返回no了。最后在搜索某条边无解的情况下,我们可以把相同大小的边略过,因为前面相同长度的边都无法安排出一种方案,在少一条相同边情况下肯定也就无法给出安排了。代码如下:#include <cstdlib>#include <cstdi 阅读全文
posted @ 2012-07-25 01:02 沐阳 阅读(305) 评论(0) 推荐(0) 编辑
摘要:首先将7种方块拆成19种方块,然后在进行dfs组合,当然如果给定的N*M不是4的倍数的时候记得直接输出0。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>using namespace std;int N, M, ans, END, G[35][35], many[20];int mp[20] = {1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7};char ss[50][6][6] = { { "####" 阅读全文
posted @ 2012-07-16 22:09 沐阳 阅读(4296) 评论(0) 推荐(0) 编辑
摘要:筛出素数然后直接暴力即可。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#define MAXN 10000using namespace std;int N, M, d, p[600005];int hash[10005], path[10005];void pre(){ int k; for (int i = 4; i <= MAXN; i += 2) { p[i] = 1; } for (int i = 3; i <= 105; i += 2) { if (!... 阅读全文
posted @ 2012-07-14 00:20 沐阳 阅读(414) 评论(0) 推荐(0) 编辑
摘要:非常简单的一道搜索题,用状态压缩加DP写了一上午,写道后面越来越感觉这题状态压缩没有什么优势,每一行都与前面的行的排列有关系,因此不能够记忆化,没算完一次要把状态清空,可惜到最后还是错了。干脆直接暴力搜索。就这样过了。代码如下:#include <cstring>#include <cstdlib>#include <cstdio>#include <algorithm>using namespace std;int N, K, hash_x[10], hash_y[10], ans;char G[10][10];void dfs(int x, 阅读全文
posted @ 2012-07-13 15:30 沐阳 阅读(252) 评论(0) 推荐(0) 编辑
摘要:之前有听说如果在一个迷宫中一直沿着某一堵墙走的话,那么一定可以走出这个迷宫,这题讲的就是这个内容。这题的问法比较奇怪,问你沿着左边的墙,右边的墙走所花的时间和最少所花的时间。该题难点就在与如何让dfs的时候能够沿着墙走。其实是有规律的,那就是往左边走是顺时针方向dfs,往右走逆时针方向走dfs,每次要确定上一次来的方向,这样能够确定你第一次试探的方向是那个方向。例如:如果从最左边的墙进入的话,那么首先选择往上走,否则向前走,再否则向下走,最后还是没法走的话就向左走(往回走),走了之后就直接return,每次走了之后绝对不会再换方向搜索。这题竟然错在了手写的找最短路的队列上。代码如下:#in.. 阅读全文
posted @ 2012-07-12 23:53 沐阳 阅读(574) 评论(0) 推荐(0) 编辑
摘要:简单的dfs搜索,题目要求是骑士可以从任意一点出发走完整个棋盘的路径。字典序输出要注意八个方向的排列顺序。代码如下:#include <cstring>#include <cstdlib>#include <cstdio>using namespace std;int N, M, dir[8][2] = {-2, -1, -2, 1, -1, -2, -1, 2, 1, -2, 1, 2, 2, -1, 2, 1};int visit[10][10], rec[100][2];bool judge(int x, int y){ if (x < 1 || 阅读全文
posted @ 2012-07-12 15:44 沐阳 阅读(274) 评论(0) 推荐(0) 编辑
摘要:该题就是求一只青蛙从1号石头跳到2号石头的所有路径中跳跃距离最大值的最小值。仔细想想的话,将原来dijkstra的dis数组赋值为这个minmax含义,同样满足贪心规则,所以就是普通的dijkstra。代码如下:#include <cstring>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cmath>#define MAXN 205using namespace std;int N;struct Node{ int x, y;}e[MAXN];do 阅读全文
posted @ 2012-07-01 09:57 沐阳 阅读(276) 评论(0) 推荐(0) 编辑
摘要:该题是做最短路专题时的题,但是可惜没有想到如何进行最短路求解。倒是觉得dfs能够得到结果,因为该题对于建立边有严格的条件,递归能够很好的解决这个约束。每次递归时将当前路径的最低等级和最高等级传递下去,然后再进行判断。这里还要注意判定环的存在。后者没有注意的话会MLE。代码如下:#include <cstring>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#define MAXN 105using namespace std;int M, 阅读全文
posted @ 2012-07-01 00:30 沐阳 阅读(263) 评论(0) 推荐(0) 编辑
摘要:首先解释下这题的名字,下沙是个地名,面的是一种公共交通工具,小是个形容词...... 对于这题那便是DFS纯暴力了,每次先到达不同的第一站,再扩展下去到第二站... 暴力枚举每一种可能,最后保留最小值。 代码如下:#include <cstdio>#include <cstring>#include <cstdio>using namespace std;int map[35][35], N, K, obj[35], RK;void DFS( int pos, int step, int dis, int &ans ){ if( step== RK 阅读全文
posted @ 2011-08-12 15:09 沐阳 阅读(531) 评论(0) 推荐(1) 编辑
摘要:可恶的模拟题,刚进入的那一步竟然不算,贡献了多次WA啊,只要注意这点应该就木有问题了。#include <cstring>#include <cstdlib>#include <cstdio>using namespace std;int N, M, sx, sy;char map[15][15], hash[15][15];bool out( int x, int y ){ if( x< 1|| x> N|| y< 1|| y> M ) { return true; } return false;}bool DFS( int &am 阅读全文
posted @ 2011-08-12 14:39 沐阳 阅读(198) 评论(0) 推荐(0) 编辑
摘要:给定一个非递减的序列,要求从这些序列中找出一系列的数相加等于要求的数。这题的主要任务就是怎样去重。 现分析如下: 对于给定的两个非递减序列,A, B, C, D 用来映射各个数的位置,2(A) 1(B) 1(C) 1(D) 以及 2(A) 2(B) 2(C) 1(D), 要求求出和为3的表达式。 显然前面的序列递归下去会首先出现A+ B的组合,由于此时A+ B已经等于了3,所以递归就会回溯,此时会形成A+ C的组合,按照正常人的思维,这个解肯定是不能够取的,但是计算机有这么聪明吗?显然还是要我们来设计各种复杂的判断...... 转回正题,我们在递归时有一个属性就是递归的层数,而该题的求解就会. 阅读全文
posted @ 2011-08-12 11:35 沐阳 阅读(417) 评论(0) 推荐(0) 编辑
摘要:简单DFS,需要注意的是最后的那个数加上一要是个素数。 代码如下:#include <cstring>#include <cstdlib>#include <cstdio>#include <cmath>using namespace std;int hash[25], rec[25], cnt;bool isprime( int x ){ if( x<= 1 ) return false; if( x== 2 ) return true; int lim= sqrt( x ); for( int i= 2; i<= lim; ++i 阅读全文
posted @ 2011-08-11 21:14 沐阳 阅读(190) 评论(0) 推荐(0) 编辑
摘要:Accepted NecklaceTime Limit: 2000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1027Accepted Submission(s): 407Problem DescriptionI have N precious stones, and plan to use K of them to make a necklace for my mother, but she won't accept a necklace which is to 阅读全文
posted @ 2011-08-11 20:38 沐阳 阅读(291) 评论(0) 推荐(0) 编辑