随笔分类 -  搜索题

摘要:题意:给定一个n * m 的矩阵(迷宫),-1 表示该位置不能通过, 1 ~ 5 表示该位置被第i个怪控制, 0 表示该位置不被任何怪控制给定起点和终点, 问Celica最少需要多少回合才能通过。当然,还有很多限制条件:1)每一个回合,Celica的初始行动值为L, 没移动一个位置,行动值-1, 当行动值减为0, 则开始下一个回合2)一旦踏入怪的所在位置,则立即会将怪杀死,怪所控制的位置也就变为0了3)当移动到一个怪所控制的位置,行动立即减为04)每到达一个位置,首先变化的是行动值, 这就意味着,如果踏入一个怪所在的位置,而且该位置是被怪所控制的情况下,那么行动值先变为0,再将怪杀死5)怪不一 阅读全文
posted @ 2013-04-10 11:15 枕边梦 阅读(373) 评论(0) 推荐(0)
摘要:题意:中文题目(略)分析:其实就是一个暴力的bfs, 关键是模拟移动,判连通,以及状态的表示。每个格子移动过程中,内部四个小三角的相对顺序是不变的,也就是移动过程中,格子是作为一个整体在移动的,,小三角只是在判连通时才用到,所以状态的表示可以将每个格子作为一个整体,这样的话,总共就是9个格子,用0~8表示,这样是否很熟悉了? 可以用类似八数码的哈希方法,用康托展开将每一个状态hash到一个整数上,剩下的就是模拟了。很惭愧,单是敲这个代码就用了快俩个小时……hdu4531#include<iostream>#include<algorithm>#include<st 阅读全文
posted @ 2013-04-07 02:07 枕边梦 阅读(251) 评论(0) 推荐(0)
摘要:题意:略分析:记忆化搜索用dp[i][j] 表示 i 次攻击得到少于j分的方案hdu4504#include<iostream>#include<algorithm>#include<stdio.h>#include<stdlib.h>#include<string.h>using namespace std;const int N = 20 + 5;const int M = 600 + 10;__int64 f[N];__int64 dp[N][M];int s[3] = {1, 2, 3};void init(){ f[0] = 阅读全文
posted @ 2013-04-06 18:52 枕边梦 阅读(258) 评论(0) 推荐(0)
摘要:hdu4527 玩转十滴水题意很明显,而且需要注意的地方在第一个测试例子已经有所体现了。就是同一时刻可能有多个水滴到达一个点,而且该位置的水滴爆破了,但也只会产生四个方向各一个水滴所以,必须处理好同一个时刻的水滴,所以用了俩个队列来处理,将同一个时刻的水滴放在一个队列中,让所有水滴都飞行一个单位时间,如果没有碰到水滴,则压入另一个队列,如果碰到了,则在该位置直接加1, 等处理完其他同一时刻的水滴之后,再判断是否存在会爆的水滴,如果会,则再产生四个水滴,压入另一个队列,以此类推,,具体看代码:hdu4527#include<iostream>#include<algorithm 阅读全文
posted @ 2013-04-02 15:33 枕边梦 阅读(275) 评论(0) 推荐(0)
摘要:分析:当N为奇数时奇偶同性可互达,N为偶数时,逆序数之和sum加上空格所在行距目标空格行的距离dis之和要和终点状态逆序数同奇偶View Code #include<iostream>#include<algorithm>#include<string>using namespace std;const int N = 300+10;int s[N*N],g[N*N];#define _cp(a,b) ((a)<=(b))int _tmp[N*N];int inv(int n,int* a){ int l=n>>1,r=n-l,i,j; i 阅读全文
posted @ 2012-04-13 09:45 枕边梦 阅读(540) 评论(0) 推荐(0)
摘要:二分距离,求最大团,看是否>=KView Code #include<iostream>#include<algorithm>#include<string>#include<math.h>using namespace std;const int N = 50+10;int dis[N][N],dd[N*N];int dp[N];bool inset[N],g[N][N];int n,best,ord[N],deg[N];bool found;inline void Memcpy(bool *d,bool *s){ for(int i=0 阅读全文
posted @ 2012-04-13 09:24 枕边梦 阅读(447) 评论(0) 推荐(0)
摘要:题意:数独游戏,不过只能用给定的多米诺骨牌填数独,而且每一个牌只能用一次,有唯一解分析:对一个未填的方格枚举三十六个牌,每一个牌有俩种摆放方式,……关键在于有没有好一点的判断方法,判断当前的放置方法是否符合数独的要求用三个数字st[3][9]表示st[0]数组表示九行的放置状态,比如,st[0][0]的每一个位表示第一行对应选了哪一个数字以此类推,st[1]表示列,st[2]表示3*3的方格代码有点冗长了,好挫…………View Code #include<iostream>#include<algorithm>#include<string>using na 阅读全文
posted @ 2012-04-10 15:26 枕边梦 阅读(220) 评论(0) 推荐(0)
摘要:题意:一个棋盘,摆了四种颜色的棋子,每次选择一个棋子消掉,同时跟它相连的也会被消掉,之后1)下方有空的棋子会往下掉,填补空的格子2)如果有整列被消的掉的,该列右边的棋子全部往左移,当然,左移的界限就是到被消掉的一整列,这个看Sample就知道了分析:棋盘不大,6*6而已。一开始的感觉就是迭代加深搜索了,再搜的过程中,优先选择相连颜色中数量最多消掉,31ms,不过爆搜也可以过,600+msView Code #include<iostream>#include<algorithm>#include<queue>using namespace std;const 阅读全文
posted @ 2012-02-26 22:41 枕边梦 阅读(305) 评论(0) 推荐(0)
摘要:题意:对一棵树上的点进行实时的增减权值和询问子树的权值和首先:单点修改以及子树查询。对整棵树dfs一遍,记录下欧拉序列。这样有一个好处,就是每一棵子树在这个序列中都是连续的,同时记录下每一棵子树的起始序列号,这样,对子树的查询就变成了一个连续区间的查询了,运用树状数组就可以解决了。那最大生成树呢?“Sailormoon girls want to cut extra branches by using minimum cost, after that..."额,这里要将多余的边减掉,用最小cost,也就是减掉之后,变成了一棵最大生成树。郁闷呀,一开始以为题目所给的cost是没用……… 阅读全文
posted @ 2012-02-26 17:02 枕边梦 阅读(563) 评论(0) 推荐(0)
摘要:题意:在T-1时间内逃出城堡,途中可能会遇到10种门或钥匙,每种门对应一种钥匙。简单的BFS,但是判断一个点能否通过不是简单的判断是否走过,而是判断通过该点时拥有的钥匙的状态是否一致。所以,判重的hash数组要多开一维,表示钥匙的状态。可以用位运算,二进制的10个位分别表示每一种钥匙的状态View Code #include<iostream>#include<algorithm>#include<queue>#define M 21using namespace std;struct node{ int x, y, t, state; node() {} 阅读全文
posted @ 2012-02-24 14:44 枕边梦 阅读(697) 评论(0) 推荐(0)
摘要:题意:在8 * 8 的跳棋棋盘上,给你两个状态,每个状态4个点,判断一个状态8步内能否到达另一个状态。分析:给定了始末状态,很典型的双向广搜。从始末两个方向进行广度搜索,理想情况下可以减少二分之一的搜索量,从而提高搜索速度。问题的关键在于状态的保存,因为四个棋子是一样的,棋盘的大小只有8*8,所以先按坐标排序之后,用二进制每三个位保存一个棋子的一个坐标,总共需要24个位。对双向广度搜索算法的改进:略微修改一下控制结构,每次while循环时只扩展正反两个方向中节点数目较少的一个,可以使两边的发展速度保持一定的平衡,从而减少总扩展节点的个数,加快搜索速度。这代码写的有点挫,用俩个BFS写的,不是用 阅读全文
posted @ 2012-02-23 19:54 枕边梦 阅读(835) 评论(0) 推荐(1)
摘要:题意:推箱子升级版,将三个箱子推到三个洞里,求最小步骤分析:思路不难,就是处理起来,细节太多,纠结死了。一个八维的布尔数组判重,差点就MLE了View Code #include <iostream>#include <algorithm>#include <queue>#define size 9using namespace std;struct Node{ int x, y; int Box[3][2];//记录三个箱子的位置 int step; char map[size][size];} start;int dir[4][2] = {{0, -1} 阅读全文
posted @ 2012-02-23 10:10 枕边梦 阅读(377) 评论(0) 推荐(0)
摘要:简单的DFS,将所有未填的位置依次保存起来,之后,对每一个未填的位置依次枚举,往下搜即可;;本来想用DLX的做的,hdu3111是过了,可是原先那个模板在这道题里就是超时,不解啊,换一个模板就过了、DFS版#include<stdio.h>struct point{ int x, y;} p[81];int num, flag, map[10][10];int judge(int n, int k){ int i, j, x, y; for(i = 0; i < 9; i++) { if(i != p[n].y && map[p[n].x][i] == k.. 阅读全文
posted @ 2012-02-22 19:34 枕边梦 阅读(891) 评论(0) 推荐(0)
摘要:精确覆盖: 首先选择当前要覆盖的列(含1最少的列),将该列和能够覆盖到该列的行全部去掉,再枚举添加的方法。枚举某一行r,假设它是解集中的一个,那么该行所能覆盖到的所有列都不必再搜,所以删除该行覆盖到的所有列,又由于去掉的列相当于有解,所以能够覆盖到这些列的行也不用再搜,删之。View Code /*DLX解决9*9的数独问题,转化为729*324的精确覆盖问题行:一共9 * 9 * 9 == 729行。一共9 * 9小格,每一格有9种可能性(1 - 9),每一种可能都对应着一行。列:一共(9 + 9 + 9) * 9 + 81 == 324 种前面三个9分别代表着9行9列和9小块,乘以9的意思 阅读全文
posted @ 2012-02-22 19:21 枕边梦 阅读(1253) 评论(0) 推荐(0)
摘要:题意:n*m的格子上有一些方块放在某些格子上,一个格子可能有几个方块,用'a'-'z'来表示方块数量。初始的时候可以选择任意空地作为Pusher初始点,Pusher选择一个方向,然后向这个方向前进直到遇到有方块的格子,Pusher把这个格子的方块清除一个,并把它向前推一格(向前不能出界),如果前面一格有方块,那么这些方合起来放在这个格子中。Pusher和有方块的格子之间至少要有一个空地才能推动分析:直接dfs,因为是special judge 找到一组解即可。View Code #include<iostream>#define N 30using 阅读全文
posted @ 2012-02-15 17:24 枕边梦 阅读(632) 评论(0) 推荐(0)
摘要:题意:在一棵苹果树上,有n个节点,第一天,只有叶节点才有苹果,苹果的数目等于该节点的编号。第二天开始,其他节点开始长苹果,对于非叶节点,只有当所有直接子节点都长了苹果之后才开始长,设它的直接子节点数目为K,则该节点的苹果数等于所有直接字节点苹果数目中的第(K + 1) / 2大。问最后根节点的苹果数目。分析:一开始感觉这题意太朦胧了,研究了半天都没明白。明白题意之后就好办很多了,类似与DP的过程,从根节点开始算,往下搜,再递推回来。用vector实现方便很多View Code #include<iostream>#include<algorithm>#include&l 阅读全文
posted @ 2012-02-14 23:36 枕边梦 阅读(412) 评论(0) 推荐(0)
摘要:题意:题中给的图填上1~8 八个数字,相连的点不能填上连续的数字分析:各种限制条件,直接dfs了View Code #include<iostream>#include<algorithm>#include<math.h>using namespace std;bool g[10][10],fil[10];//g[10][10]记录点与点之间是否相连,fil[10]记录该数字是否已经选过int a[10],ans[10],num;//ans[]保存路径void dfs(int deep,int move[]){ if(deep==8)//选完了 { if(! 阅读全文
posted @ 2012-02-14 15:41 枕边梦 阅读(291) 评论(0) 推荐(0)
摘要:题意:这题意真的十分费解,看了好久才明白。给定N个数字,产生p个子序列,序列满足:先按长度排列,而且子序列本身是递增的;之后,按子序列中各个数字所在位置排序。最主要的就是判重还有“子序列必须满足递增”具体的解释看代码吧View Code #include<iostream>#include<algorithm>using namespace std;struct node{ int v,pos;}ans[1001];int a[1001],n,p,nnum,total;bool check(int s,int e)//判重,我觉得是这道题目的关键{ for(int i= 阅读全文
posted @ 2012-02-14 01:39 枕边梦 阅读(354) 评论(0) 推荐(0)
摘要:题意:还是类似迷宫问题,已知起点和终点,在规定时间内求出到达终点的最少时间。有俩种行走方式1)飞行:除了遇到‘#’ 以外,任何地方都能穿过,但需要消耗1s,同时消耗1 魔法值注意:理论上遇到一个‘@’要消耗俩点魔法值,因为离开这个‘@’ 要消耗2点魔法值2)行走:有俩种情况不能走,1,遇到‘#’;2当前点是‘@’ 或者遇到的点是‘@’View Code #include<iostream>#include<algorithm>#include<queue>using namespace std;char g[100][100];bool vis[88][88 阅读全文
posted @ 2012-02-13 15:10 枕边梦 阅读(277) 评论(0) 推荐(0)
摘要:题意:射箭游戏,已知箭头的初始位置是(0,0),速度为v,靶的位置为(x,y),要求算出射中靶心的最小的角度,若不能射中,则输出-1分析:借鉴之前几道三分的思想,很明显的一点是,关于高度h关于角度θ的函数是凸函数,首先三分枚举角度值,求出到达x时的最大高度利用最大高度判断能否射中,若能,则继续二分θ逼近y,最后求出最小的θ当然,此题还存在纯物理公式的解法参考下面的博客http://www.cnblogs.com/newpanderking/archive/2011/08/25/2153590.htmlView Code #include<iostream>#include<a 阅读全文
posted @ 2012-02-13 01:13 枕边梦 阅读(453) 评论(0) 推荐(0)