dfs算法是深度搜索算法。从某一节点开始遍历直至到路径底部,如果不是所寻找的,则回溯到上个节点后,再遍历其他路径。不断重复这个过程。一般此过程消耗很大,需要一些优化才能保持算法的高效。

  hdu1010:(奇偶剪枝)

    主要题意是一只小狗为了一块骨头,然后进入迷宫。当它拿起骨头的时候,迷宫开始下沉。小狗才发这迷宫是个陷阱。这迷宫只有一个门,小狗只能在规定时间内跑到到门这里才能顺利出逃。另外,小狗每跑过一块,该块就会下沉。因此不能过早或者过晚到门。(题目挺有意思)

    刚开始刷题时,没有用剪枝,超时了。使用奇偶剪枝+dfs后,可以直接过。奇偶剪枝的内容可以百度。

    

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
/*
'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door;
'.': an empty block.
*/

int n,m,t;
bool flag = false;
int doorI,doorJ;
char blocks[7][8];
bool isEnd(int curI,int curJ,int curT)
{
    if(flag)    return true;
    if(curT > t) return true;
    if(curT == t)
    {
        if(curI == doorI && curJ == doorJ)
            flag = true;
        return true;
    }
    if(curI < 0 || curJ < 0 || curI >= n || curJ >=m)
        return true;
    if(blocks[curI][curJ] == 'X')   return true;
    if(curI==doorI && curJ == doorJ)    return true;
    return false;
}
void dfs(int curI,int curJ,int curT)
{
    if(isEnd(curI,curJ,curT))   return;
    char temp = blocks[curI][curJ];
    blocks[curI][curJ] = 'X';
    dfs(curI-1,curJ,curT+1);
    dfs(curI+1,curJ,curT+1);
    dfs(curI,curJ-1,curT+1);
    dfs(curI,curJ+1,curT+1);
    blocks[curI][curJ] = temp;
}

int main()
{
    while(~scanf("%d%d%d",&n,&m,&t),n&&m&&t)
    {
        flag = false;
        int startI=0,startJ=0;
        for(int i=0;i<n;++i)
        {
            scanf("%s",blocks[i]);
            for(int j=0;j<m;++j)
                if(blocks[i][j]=='S')
                    startI = i,startJ = j;
                else if(blocks[i][j]=='D')
                    doorI = i,doorJ = j;
        }
        //ΌτΦ¦
        if(abs(startI-doorI)+abs(startJ-doorJ)> t ||(startI + startJ + doorI + doorJ + t)%2)
        {
            printf("NO\n");
            continue;
        }
        dfs(startI,startJ,0);
        if(flag)   printf("YES\n");
        else       printf("NO\n");
    }
    return 0;
}
View Code

 

  hdu2553:(简单题)

    N皇后问题,使用dfs一次性把1到10的值算出来,然后直接输出Hash[n]就行了,否则会超时。

 

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

int cnt;
int n;      //n不大于10
int f[10];
int Hash[11];
bool isEnd(int curI)
{
    for(int i=0;i<curI-1;++i)
        if(f[curI-1]==f[i]||
           f[curI-1]-f[i]==curI-i-1||
           f[i]-f[curI-1]==curI-i-1)
            return true;
    if(curI == n)
    {
        ++cnt;
        //注释的是输出代码,可以打开注释,看具体的输出
        /*for(int i=0;i<n;++i)
        {
            for(int j=0;j<n;++j)
            {
                if(f[i] == j)   printf("1 ");
                else            printf("0 ");
            }
            printf("\n");
        }
        printf("\n");
        */
        return true;
    }
    return false;

}
void dfs(int curI)
{
    if(isEnd(curI)) return;
    for(int j=0;j<n;++j)
    {
        f[curI] = j;
        dfs(curI+1);
    }
}
int main()
{
    for(n=1;n<=10;++n)
    {
        cnt = 0;
        memset(f,0,sizeof(0));
        dfs(0);
        Hash[n] = cnt;
    }
    while(~scanf("%d",&n),n)
    {
        printf("%d\n",Hash[n]);
    }
    return 0;
}
View Code