poj 几道简单的搜索题 (一)

题目:poj 2488 A Knight's Journey
题意:

给一个m*n的棋盘,马走日,给出一条字典序最小的马的路线来走完整个棋盘?

分析:

如果能走完棋盘,那么从(1,1)点dfs即可,因为他能走完整个棋盘嘛,总有一步会经过(1,1),所以从(1,1)出发就能到其他所有点。

为了保证字典序,在枚举方向时顺序要保证x轴优先,然后y轴。

#include
#include
#include
#include
#include
using namespace std;
const int N=33;
typedef pairpii;
vectorans;
int dx[][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};
int n,m;
bool vis[N][N];
bool dfs(int x,int y,int step)
{
    if(step==n*m)return 1;
    for(int i=0;i<8;i++){
        int xx=dx[i][0]+x;
        int yy=dx[i][1]+y;
        if(xx<1||yy<1||xx>n||yy>m||vis[xx][yy])continue;
        vis[xx][yy]=1;
        ans.push_back(make_pair(xx,yy));
        if(dfs(xx,yy,step+1)) return 1;
        vis[xx][yy]=0;
        ans.pop_back();
    }
    return 0;
}
int main()
{
    int T;scanf("%d",&T);
    for(int cas=1;cas<=T;cas++){
        ans.clear();
        scanf("%d%d",&m,&n);
        ans.push_back(make_pair(1,1));
        memset(vis,0,sizeof(vis));
        vis[1][1]=1;
        printf("Scenario #%d:\n",cas);
        if(dfs(1,1,1)){
            for(int i=0;i

题目:poj 3009

题意:

滚小球,小球刚开始在起点S,每次可以往四个方向扔出,扔出后小球一直滚动,直到碰到砖块(砖块碰到后消失)或者到达终点E。问小球到E的最短路?

分析:

虽然是到类似于最短路的题目,但是似乎bfs是不行的,因为每次球发生碰撞后会改变地图,有可能出现更优解!所以要dfs找出所有的可能解(所以数据范围才小),但是要剪枝,不然会超时。

#include
using namespace std;
const int INF=0x3f3f3f3f;
const int N=22;
int g[N][N];
int w,h,sx,sy;
int dx[][2]={{-1,0},{1,0},{0,-1},{0,1}};
int ans=INF;
void dfs(int x,int y,int step)
{
    if(step>=10||step>=ans)return; //剪枝
    for(int i=0;i<4;i++){
        int xx=dx[i][0]+x;
        int yy=dx[i][1]+y;
        if(g[xx][yy]==1)continue;
        while(xx>=0&&xx=0&&yy

题目:poj 1321

题意:

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n

分析:

要找所有方案,显然是要dfs找出所有可能解。因为放了的棋子不能在同一行或者同一列,很容易想到开两个数组标记一下有棋子的行和列,但是这似乎还不能解决这个问题,因为可能出现重复(比如这种方案是AB两点,另一种方案是BA两点),为了防止重复,可以逐行枚举,这样就不会出现重复的情况了。

#include
#include
using namespace std;
const int N=10;
int n,k;
bool visy[N],g[N][N];
char s[N];
int ans;
void dfs(int row,int step)
{
    if(step==k){
        ans++;return;
    }
    for(int i=row;i


题目:poj 2251

题意:

给出一个三维的图,求S到E的最短路

分析:

裸的bfs

#include
#include
#include
using namespace std;
#define mp make_pair
const int N=33;
typedef pairpii;
typedef pairstate; //步数,层,行,列,可能写个struct清晰点QAQ
char g[N][N][N];
bool vis[N][N][N];
int C,L,R,sl,sc,sr; //层数,行数,列数,开始的层行列
int d[][3]={{0,0,-1},{0,0,1},{0,-1,0},{0,1,0},{-1,0,0},{1,0,0}};
int bfs()
{
    queueq;
    q.push(mp(mp(0,sl),mp(sr,sc)));
    memset(vis,0,sizeof(vis));
    vis[sl][sr][sc]=1;
    while(!q.empty()){
        state t=q.front();q.pop();
        int step=t.first.first,l=t.first.second,r=t.second.first,c=t.second.second;
        for(int i=0;i<6;i++){
            int tl=l+d[i][0],tr=r+d[i][1],tc=c+d[i][2];
            if(tl<0||tl==L||tr<0||tr==R||tc<0||tc==C||vis[tl][tr][tc]||g[tl][tr][tc]=='#')continue;
            if(g[tl][tr][tc]=='E')return step+1;
            vis[tl][tr][tc]=1;
            q.push(mp(mp(step+1,tl),mp(tr,tc)));
        }
    }
    return -1;
}
int main()
{
    while(~scanf("%d%d%d",&L,&R,&C)&&(L+R+C)){
        for(int l=0;l










转载于:https://www.cnblogs.com/01world/p/5762842.html

你可能感兴趣的:(数据结构与算法)