搜索-DFS

洛谷 P1706

 https://www.luogu.com.cn/problem/P1706

程序模板:

 

#include<bits/stdc++.h>
using namespace std;

//定义变量 n,当前排列记录数组,当前排列数字是否使用数组 
int n,used[10],curRow[10];

void dfs(int k){
    //满足退出条件 输出当前排列数组 
    
    
    // 1~n全部展开 
    for(int i=1;i<=n;i++){
        //判断当前数字未使用进入 
        //当前数组是否使用,在定义数组是否设置
        
         
        //设置
        // 记录到当次排列数组
         
        //递归dfs 
        
        //恢复 
    } 
}
int main(){
    //输入 
    //调用dfs 0开始 深度优先搜索 
    return 0;
}

 

 

 

 

洛谷 P2404

 https://www.luogu.com.cn/problem/P2404

程序模板:

#include <iostream>
using namespace std;
//输入要拆分的自然数和当次拆分过程中产生的数  
int n, a[200];
//deep dfs深度每次加1  当次拆分的自然数 7 6 
void dfs(int deep, int k){
    //退出条件 
    if(k == 0){
        if(deep == 2)//只有一个数时,不拆分 
            return;
        // 1 ~ deep 循环打印 注意 +和换行 
        
//        coding
        
        return;
    }
    // 每次对k个数进行递归拆分 
    for(int i = a[deep-1]; i <= k; i++){
        //当前数放进数组 
        
        //coding
        
        //对去除当次的数,再进行递归拆分  dfs deep+1  , k-i
        
        //coding
        
    }
}

int main(){
    cin >> n;
    //从自然数1开始拆分 
    a[0] = 1;
    dfs(1, n);
    return 0;
}

 

 

 

 

 

 

洛谷 P1605

 https://www.luogu.com.cn/problem/P1605

程序模板:

#include<bits/stdc++.h>
using namespace std;

int n,m,coun=0,t;
int sx,sy,fx,fy;
int mp[6][6];//标记是否为障碍物 0为障碍物 1为无障碍物 
int vis[6][6]={0};//全为没走过
int dx[4]={0, 0,1,-1};
int dy[4]={1,-1,0, 0};
int b,c;//障碍坐标数 

void dfs(int x,int y){
    //到达退出 退出条件x==fx && y==fy coun累加 
    
    //四个方向深度搜索 
    for(int i=0;i<=3;i++){
        //判断mp mp[x+dx[i]][y+dy[i]]==1 是否有障碍物 vis[x+dx[i]][y+dy[i]]==0是否走过 
        if(mp[x+dx[i]][y+dy[i]]==1&&vis[x+dx[i]][y+dy[i]]==0){
            //标记为已走过
            
            //coding 
            
            //继续深度搜索x+dx[i] ,y+dy[i]
            
            //coding
            
            //回溯一步
            
            //coding
        }
    }
}

int main(){
    cin>>n>>m>>t;
    cin>>sx>>sy>>fx>>fy;
    vis[sx][sy]=1;//开始位置第一步走
    //所有的标记为无障碍物 mp 二维数组都为1 
    
    //coding
    
    //把障碍物标记处理 循环对应有障碍物mp位置设置为0 
    
    //coding
    
    dfs(sx,sy);//开始搜索
    printf("%d",coun);
    return 0;
}

 

 

 

 

 

 

 

 

洛谷 P1101

 https://www.luogu.com.cn/problem/P1101

程序模板:

#include<bits/stdc++.h>
using namespace std;
const char key[8]={'y','i','z','h','o','n','g','\0'};
char s[105][105];
int n;
//x y 的8个方向找 
int dirx[8]={-1,-1,-1,0,0,1,1,1},diry[8]={-1,0,1,-1,1,-1,0,1};
int tx[105],ty[105];//记录当次查找每个字母依次位置,用来恢复现场
int used[105][105];//记录所有出发点 
int locx,locy;//当前出发点

//回溯打标,找到单词所有字母后,把这些字母的位置都打标 
void markBack(int x,int y){
    while (x!=-1&&y!=-1){//如果不是这条路的则是-1,前面定义了
        used[x][y]=1;//将当前坐标打上标记
        x=tx[x];//回到我们是怎么走过来的,即到上一步的地方去
        y=ty[y];
    }
}

//x,y当前坐标 rank已经找到了几个  fx dfs找单词的方向 
void dfs (int x,int y,int rank,int fx){
    // y start找了一个 i rank=1 rank=6时 找全了 
    if (rank==6){
        used[locx][locy]=1;//此出发点已经找完 
        markBack(x,y);
        return;
    }
    int kx,ky;
    kx=x+dirx[fx];ky=y+diry[fx];//临时变量,下一个坐标 
    if (kx<0||ky<0||kx>=n||ky>=n)//防止越界
        return;
    if (s[kx][ky]==key[rank+1]){
        tx[kx]=x;//记录下找到下一个字符的路径,表示kx是从x这来的
        ty[ky]=y;
        dfs(kx,ky,rank+1,fx);//进行下一步搜索
        tx[kx]=ty[ky]=-1;//把路径恢复 
    }
}
//从y的位置开始 往8个方向查找 
void start (int x,int y){//最开始找到的'y'的坐标
    int kx,ky,k;//临时坐标
    for (k=0;k<8;k++){
        kx=x+dirx[k];ky=y+diry[k];//各个方向都进行查找
        if (kx<0||ky<0||kx>=n||ky>=n)//不能越界
            continue;
        if (s[kx][ky]==key[1]){//如果找到了在方向上有'i'就往这个方向继续查找
            locx=x;//先记录下我们的出发点
            locy=y;
            dfs (kx,ky,1,k);
        }
    }
}
// 输出 used 字母打过标,说明用过,否则输出 * 
void print (void){
    
    //循环输出used数组 打标的原样输出,否则输出 * 
    
}

int main (){
    cin>>n;//输入n
    memset(tx,-1,sizeof(tx));//将每个路径都记为-1
    memset(ty,-1,sizeof(ty));
    for (int i=0;i<n;i++)
        for (int j=0;j<n;j++)
            cin>>s[i][j];
    for (int i=0;i<n;i++)
        for (int j=0;j<n;j++)
            if (s[i][j]==key[0])//如果找到了符合条件的开头字符'y'
                start(i,j);//先进行处理
    print();//输出
    return 0;
}

 

 

子集和

http://iai.sh.cn/problem/476

#include<bits/stdc++.h>
using namespace std;

int a[30];
int sum = 0,n,t,ans;//n为集合的大小,t为目标值 
void dfs(int step){
    if (step == n){//递归n个数 
        if (sum == t){//sum和目标值相同 一次方案 
            ans++;
            return;
        }
    }else{
        sum += a[step];
        dfs(step + 1);//取当前值计算一次 
        sum -= a[step];//回溯时先还原
        dfs(step + 1);//不取当前值计算一次 
    }
}
int main(){
    cin>>n>>t;
    for (int i = 0; i < n; i++)
        cin>>a[i];
    dfs(0);//从第一个数开始取 
    if(ans>0){
        cout<<"Yes";
    }else{
        cout<<"No";
    }
    return 0;
}

 

四方定理

http://iai.sh.cn/problem/477

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL n;
const int maxC=5e4+10;
LL ans[maxC];
//step 深度几个数 
//sum 几个数的和 
void dfs(LL step, LL sum){
    if (step>4){//深度4以后 保证有四个数相加 
        if (sum==n){//四个数的和等于n 
            for (LL i=1; i<=4; i++){//输出这四个数 
                cout<<ans[i]<<" ";
            }
            cout<<"\n";
        }
        return ;
    }
    for (LL i=0; i*i<=n; i++){
        if (ans[step-1]<=i){//前一个数必须小于等于当前数 
            ans[step]=i;//当前数记录到数组 
            dfs(step+1,sum+i*i);//递归下一个数 总和加上当前数 
        }
    }
}
int main(){
    cin>>n;
    dfs(1,0);//第一个数 此时和为0 
    return 0;
}

 

八皇后

搜索-LETTERS

noi 1700 输出 八皇后问题

输出第几个八皇后

迷宫-是否可以到底某个坐标

红与黑-计算可到达的瓷砖数

棋盘问题

马走日

放苹果

posted @ 2021-01-03 17:28  new-code  阅读(62)  评论(0编辑  收藏  举报