dfs恢复现场以及回溯的理解

这种搜索树dfs就是一层一层来看,如果这一层的情况考虑结束了之后也就是都没有解了的时候,就开始回溯,回到上一层再判断,一定要记得回溯要恢复现场,先恢复现场再回溯,就是新的一层不能有任何标记
这一题不能走过重复的点,回溯的时候相当于换另一种选择的方式,原来标记过的点就需要把标记去掉
上一题单词接龙,每个单词不能使用超过两次,所以需要记录每个单词用过多少次,在回溯的时候,也就是这一层的单词都不可能匹配,这是新的一层,之前已经次数已经++了,这个时候要把之前加过的减掉(因为没有用过啊),然后退出这个新的一层,返回到其他的分支

单词接龙代码:

复制代码
#include<iostream>
using namespace std;
const int N=100;
string ch[N];
int g[N][N];
int used[N];
int n,res;
void dfs(string dragon,int num)//龙和当前使用的字符串的编号
{
    res=max(res,(int)dragon.size());
    used[num]++;
    for(int i=0;i<n;i++)//新的字符串 
    {
        if(g[num][i]&&used[i]<2)//能匹配上并且使用使用的次数少于两次 
        {
            dfs(dragon+ch[i].substr(g[num][i]),i);
        }
    }//如果全都不符合条件就退出循环,返回上一个分支,这个时候就是一个回溯的过程,把之前用过的字符次数-1 
    used[num]--;//回溯 

} 
int main(){
    cin>>n;
    for(int i=0;i<n;i++) cin>>ch[i];
    char c;
    cin>>c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
            string a=ch[i],b=ch[j];
            for(int k=1;k<min(a.size(),b.size());k++)//匹配的一个过程 
                if(a.substr(a.size()-k)==b.substr(0,k))
                {
                    g[i][j]=k;//重合了多少个字符
                    break; 
                } 
        }
    for(int i=0;i<n;i++)
        if(ch[i][0]==c)
            dfs(ch[i],i);//开始dfs
    cout<<res;
    return 0; 
}
/*
每个都能两次,也是树的形式,每个单词伸出去一个分支 
*/
复制代码

马走日的代码:

复制代码
#include<iostream>
using namespace std;
int n,m,x,y,sum;
const int N=1010;
bool st[N][N];
int dx[8]={-1,-1,-2,-2,1,1,2,2};
int dy[8]={2,-2,1,-1,2,-2,1,-1};
void dfs(int x,int y,int u)
{
    if(u==n*m)
    {
        sum++;
        return ;
    }
    st[x][y]=true;
    for(int i=0;i<8;i++)
    {
        int xx=x+dx[i],yy=y+dy[i];
        if(xx>=0&&yy>=0&&xx<n&&yy<m&&!st[xx][yy])
        {
            dfs(xx,yy,u+1);
        }
    }//这一层结束,所有的情况没了之后返回上一层
    st[x][y]=false;//回溯 
}
int main(){
    int T;
    cin>>T;
    while(T--)
    {
        sum=0;
        cin>>n>>m>>x>>y;
        dfs(x,y,1);
        cout<<sum<<endl;
    }
    return 0;
} 
复制代码

 

posted @   小志61314  阅读(634)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示