poj 3009 dfs

背景:dfs,再加点模拟,各种代码疏漏错误wa了三次!!也有变量名使用不规则照成的。比如临时变量我我就应该用temp,buffer,key,三个变量名来表示。

思路:每一个点四个方向的dfs,到达终点就判断最少步数。

bfs的思路:这个是经典的最短路问题,但是缺点是,地图会改变而bfs没办法像dfs那样容易回溯,方法就是把地图直接放在每一个坐标上,也就是定义一个结构体:

struct place{
     int x,y,step;
     int diagram[M][M];//每一个坐标点都付一个图
}

我的代码:

#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include <iostream>
#define LL long long int
#define INF 0x3fffffff
#define M 29
using namespace std;
int n,m,diagram[M][M],ans;
struct place{int x,y,step;}s,temp1;

void dfs(place temp){
    #ifdef Ms
    for(int i=1;i <= n;i++){
            for(int j=1;j <= m;j++){
                printf("%d ",diagram[i][j]);
            }
            printf("\n");
    }
    printf("\n");
    #endif // LOCAL
     if(temp.step+1 > 10 || temp.step+1 > ans) return;
     for(int i=temp.x-1;i > 0;i--){//向上走。
         if(diagram[i][temp.y] == 3 && diagram[temp.x-1][temp.y] != 1){if(temp.step+1 < ans) ans=temp.step+1;return;}
         if(diagram[i][temp.y] == 1 && diagram[temp.x-1][temp.y] != 1){
            temp1.x=i+1;
            temp1.y=temp.y;
            temp1.step=temp.step+1;
            diagram[i][temp.y]=0;
            dfs(temp1);
            diagram[i][temp.y]=1;
            break;
         }
     }
     for(int i=temp.x+1;i <= n;i++){//向下走。
         if(diagram[i][temp.y] == 3 && diagram[temp.x+1][temp.y] != 1){if(temp.step+1 < ans) ans=temp.step+1;return;}
         if(diagram[i][temp.y] == 1 && diagram[temp.x+1][temp.y] != 1){
            temp1.x=i-1;
            temp1.y=temp.y;
            temp1.step=temp.step+1;
            diagram[i][temp.y]=0;
            dfs(temp1);
            diagram[i][temp.y]=1;
            break;
         }
     }
    for(int i=temp.y+1;i <= m;i++){//向右走。
        if(diagram[temp.x][i] == 3 && diagram[temp.x][temp.y+1] != 1){if(temp.step+1 < ans) ans=temp.step+1;return;}
         if(diagram[temp.x][i] == 1 && diagram[temp.x][temp.y+1] != 1){
            temp1.x=temp.x;
            temp1.y=i-1;
            temp1.step=temp.step+1;
            diagram[temp.x][i]=0;
            dfs(temp1);
            diagram[temp.x][i]=1;
            break;
         }
     }
     for(int i=temp.y-1;i > 0;i--){//向左走。
         if(diagram[temp.x][i] == 3 && diagram[temp.x][temp.y-1] != 1){if(temp.step+1 < ans) ans=temp.step+1;return;}
         if(diagram[temp.x][i] == 1 && diagram[temp.x][temp.y-1] != 1){
            temp1.x=temp.x;
            temp1.y=i+1;
            temp1.step=temp.step+1;
            diagram[temp.x][i]=0;
            dfs(temp1);
            diagram[temp.x][i]=1;
            break;
         }
     }
}

int main(void){
    while(scanf("%d%d",&m,&n),m*m+n*n){
        memset(diagram,0,sizeof(diagram));
        for(int i=1;i <= n;i++)
            for(int j=1;j <= m;j++){
                scanf("%d",&diagram[i][j]);
                if(diagram[i][j] == 2){
                    s.x=i;
                    s.y=j;
                    diagram[i][j]=0;
                }
            }
        ans=INF;
        s.step=0;
        dfs(s);
        if(ans == INF) printf("-1\n");
        else printf("%d\n",ans);
    }
    return 0;
}
				
时间: 2024-08-13 16:41:16

poj 3009 dfs的相关文章

poj 3009 DFS +回溯

Curling 2.0 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14567   Accepted: 6082 Description On Planet MM-21, after their Olympic games this year, curling is getting popular. But the rules are somewhat different from ours. The game is

POJ 1979 POJ 3009 AOJ 0033 AOJ 0118 [搜索类题目][0033贪心模拟]

/** POJ 1979 BFS */ #include <stdio.h> #include <string.h> #include <iostream> #include <queue> using namespace std; const int N = 20 + 5; int mp[N][N]; int sx,sy; int n, m; int vis[3000]; int dirx[] = {0, 1, 0, -1}; int diry[] = {

poj 3009 Curling 2.0 【DFS】

题意:从2出发,要到达3, 0可以通过,碰到1要停止,并且1处要变成0, 并且从起点开始沿着一个方向要一直前进,直至碰到1(或者3)处才能停止,(就是反射来反射去知道反射经过3).如果反射10次还不能到达3,就输出-1. 策略:深搜. 易错点,方向不容易掌握,并且,出题人把n, m顺序反了. 代码: #include<stdio.h> #include<string.h> int map[25][25]; int ans, n, m; const int dir[4][2] = {

poj 3009 Curling 2.0 (dfs)

id=3009">链接:poj 3009 题意:在一个冰面网格板上,有空白处(无障碍),和障碍块.有一个小石头,给定其起点和终点.求从起点到终点的最小步数 规则:小石头不能在障碍区运动,一旦从某一方向開始运动,不会改变方向,也不会停止.除非碰到障碍物或到达终点才会停止,这为一步.若碰到障碍物.小石头将停在障碍物的旁边,被碰到的一个障碍物将消失. 输入:1代表障碍物(不可到达),0代表空白区,2,代表起点.3代表终点 输出:若小石头能到达终点,且步数最多为十步,输出最小步数,否则输出-1.

POJ 3321 DFS序+线段树

单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4:   5: #include <cstdio> 6: #include <cstring> 7: #include <cctype> 8: #include <algorithm> 9: #include <vector> 10: #include <iostream> 1

poj 1167 DFS

1 /* 2 题意:给出0-59的一排数字表示某一时刻出现了1辆bus,其中数字重复出现表示多辆bus同时出现,这些bus是 3 由多个bus线路组成的,每条线路都有一个时间间隔,而且同一线路的bus在0-59肯定会出现两次或以上,如果 4 有两条线路的间隔相同且到达时刻相同也算作两条不同的线路,问最少有多少条线路. 5 6 题解:DFS 7 这题是一题相对较难的搜索,关键在于找出状态以及剪枝: 8 对于每条bus线路都由开始时刻start和间隔interval组成,这样就找出了表示一条线路的状

Oil Deposits(poj 1526 DFS入门题)

http://poj.org/problem?id=1562 Oil Deposits Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12595   Accepted: 6868 Description The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp wor

poj 1069 DFS+剪枝

1 /* 2 题意:给出一个边长为S的六边形,再给出n种边长不同的三角形,所有的长度均为整型,问这n种三角形是否 3 能够拼成这个六边形. 4 5 题解:DFS+剪枝 6 这题的关键是图的表示方法以及剪枝,图我用了一个二维数组直接表示: 7 111111111111111111111 8 111110000000000011111 9 111100000000000001111 10 111000000000000000111 11 110000000000000000011 12 100000

POJ 3009 Curling 2.0 回溯,dfs 难度:0

http://poj.org/problem?id=3009 如果目前起点紧挨着终点,可以直接向终点滚(终点不算障碍) #include <cstdio> #include <cstring> using namespace std; const int maxn = 21; int maz[maxn][maxn]; int n,m; const int dx[4] = {1,-1,0,0}; const int dy[4] = {0,0,1,-1}; bool in(int x,