DFS(深搜/4/18)

P1605 迷宫

一开始把newx和newy都设置成了全局变量,结果一直错,后来才发现不能这样,因为回溯的时候,回溯到前面的时候,newx newy还是后面的,没有回来,而局部变量的话就不用担心作用域内改变

#include <bits/stdc++.h>
using namespace std;
int n,m,sum;//必须都要定义在前面,养成习惯
int a[1005][1005];
int vis[60][60];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//定义四个方向
int x,y,beginx,beginy,endx,endy,t;
void dfs(int x,int y)
{
    if(x==endx&&y==endy){sum++;return;}//这一句要记得不要写在for里面
    for(int i=0;i<4;i++)
    {
        int newx=x+dir[i][0];//这里必须是局部变量不能是全局变量,否则回溯不成功!!!
        int newy=y+dir[i][1];//若是全局变量则会永久加,当回溯的时候,只会回溯最后那一个
        if(newx>0&&newx<=n&&newy>0&&newy<=m&&a[newx][newy]==0&&vis[newx][newy]==0)//newx对应的是二维数组的 第一维 !!!即行数也就是n!
        {
            a[newx][newy]=1;
            dfs(newx,newy);
            a[newx][newy]=0;
        }
    }
}
int main()
{
    cin>>n>>m;
    cin>>t;
    cin>>beginx>>beginy>>endx>>endy;
    while(t--)
    {
        cin>>x>>y;
        vis[x][y]=1;
    }
    vis[beginx][beginy]=1;
    dfs(beginx,beginy);
    cout<<sum<<endl;
    return 0;
}

P1219 [USACO1.5]八皇后 Checker Challenge

也是深搜+回溯,不过标记的有四个数组,这个倒是挺难想的

#include <bits/stdc++.h>
using namespace std;
int n,m,sum,newy;//必须都要定义在前面,养成习惯
int ans;
int row[20],line[20],ma[20],fu[20];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//定义四个方向
void print()
{
    for(int i=0;i<n;i++)printf("%d ",line[i]);
    printf("\n");
}
void dfs(int x,int step)
{

    if(step==n)
    {
        ans++;
        if(ans<=3)print();
        return ;
    }
    for(int i=1;i<=n;i++)
    {
        if(!row[i]&&!line[step]&&!ma[n-i+step]&&!fu[i+step])
        {
            row[i]=1;line[step]=i;ma[n-i+step]=1;fu[i+step]=1;
            dfs(i,step+1);
            row[i]=0;line[step]=0;ma[n-i+step]=0;fu[i+step]=0;
        }
    }
}

int main()
{

    cin>>n;
    dfs(0,0);
    cout<<ans;
    return 0;
}

P1025 数的划分

两个易超时的点:
1.条件满足时的判断
2.合理的剪枝

#include <bits/stdc++.h>
using namespace std;
int ans;//必须都要定义在前面,养成习惯
int n,k;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//定义四个方向
void dfs(int past,int value,int step)
{
    if(step==k)
    {
        if(value==n)ans++;
        return ;
    }

    for(int i=past;value+i*(k-step)<=n;i++)//剪枝
    {
        int new_value;
        if(i>=past)
        {
            new_value=value+i;
            dfs(i,new_value,step+1);
        }
    }
}
int main()
{
    cin>>n>>k;
    dfs(1,0,0);
    printf("%d\n",ans);
    return 0;
}

P1057 传球游戏

因为剪枝后也t了3个点,又看到数据nm都是30以内,所以直接打表

#include <bits/stdc++.h>
using namespace std;
int n,m,sum,newy;//必须都要定义在前面,养成习惯
int ans;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//定义四个方向
void dfs(int x,int step)
{
    if(step==m)
    {
        if(x==1)ans++;
        return ;
    }
    if(x+m-step<=n&&x-m+step>1)return;
    int newx=x+1;
    if(newx>n)dfs(newx-n,step+1);
    else dfs(newx,step+1);
    newx=x-1;
    if(newx==0)dfs(newx+n,step+1);
    else dfs(newx,step+1);
}
int main()
{
    int a[31][30]={{0,2,2,6,10,22,42,86,170,342,682,1366,2730,5462,10922,21846,43690,87382,174762,349526,699050,1398102,2796202,5592406,11184810,22369622,44739242,89478486,178956970,357913942},{0,2,0,8,0,32,0,128,0,512,0,2048,0,8192,0,32768,0,131072,0,524288,0,2097152,0,8388608,0,33554432,0,134217728,0,536870912},{0,2,0,6,2,20,14,70,72,254,330,948,1430,3614,6008,13990,24786,54740,101118,215766,409640,854702,1652090,3396916,6643782,13530350,26667864,53971350,106914242,215492564},{0,2,0,6,0,22,0,86,0,342,0,1366,0,5462,0,21846,0,87382,0,349526,0,1398102,0,5592406,0,22369622,0,89478486,0,357913942},{0,2,0,6,0,20,2,70,18,252,110,924,572,3434,2730,12902,12376,48926,54264,187036,232562,720062,980674,2789164,4086550,10861060,16878420,42484682,69242082,166823430},{0,2,0,6,0,20,0,72,0,272,0,1056,0,4160,0,16512,0,65792,0,262656,0,1049600,0,4196352,0,16781312,0,67117056,0,268451840},{0,2,0,6,0,20,0,70,2,252,22,924,156,3432,910,12870,4760,48622,23256,184796,108528,705894,490314,2708204,2163150,10430500,9373652,40313160,40060078,156305070},{0,2,0,6,0,20,0,70,0,254,0,948,0,3614,0,13990,0,54740,0,215766,0,854702,0,3396916,0,13530350,0,53971350,0,215492564},{0,2,0,6,0,20,0,70,0,252,2,924,26,3432,210,12870,1360,48620,7752,184756,40698,705434,201894,2704204,961400,10401250,4440150,40123152,20030010,155172330},{0,2,0,6,0,20,0,70,0,252,0,926,0,3460,0,13110,0,50252,0,194446,0,758100,0,2973350,0,11716252,0,46333566,0,183739940},{0,2,0,6,0,20,0,70,0,252,0,924,2,3432,30,12870,272,48620,1938,184756,11970,705432,67298,2704156,354200,10400602,1776060,40116656,8584290,155118390},{0,2,0,6,0,20,0,70,0,252,0,924,0,3434,0,12902,0,48926,0,187036,0,720062,0,2789164,0,10861060,0,42484682,0,166823430},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,2,12870,34,48620,342,184756,2660,705432,17710,2704156,106260,10400600,592020,40116600,3121560,155117522},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12872,0,48656,0,185136,0,708512,0,2725408,0,10532160,0,40870080,0,159189120},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,2,48620,38,184756,420,705432,3542,2704156,25300,10400600,161460,40116600,950040,155117520},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48622,0,184796,0,705894,0,2708204,0,10430500,0,40313160,0,156305070},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,2,184756,42,705432,506,2704156,4600,10400600,35100,40116600,237510,155117520},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184758,0,705476,0,2704708,0,10405800,0,40157550,0,155402532},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184756,2,705432,46,2704156,600,10400600,5850,40116600,47502,155117520},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184756,0,705434,0,2704204,0,10401250,0,40123152,0,155172330},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184756,0,705432,2,2704156,50,10400600,702,40116600,7308,155117520},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184756,0,705432,0,2704158,0,10400652,0,40117356,0,155125640},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184756,0,705432,0,2704156,2,10400600,54,40116600,812,155117520},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184756,0,705432,0,2704156,0,10400602,0,40116656,0,155118390},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184756,0,705432,0,2704156,0,10400600,2,40116600,58,155117520},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184756,0,705432,0,2704156,0,10400600,0,40116602,0,155117580},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184756,0,705432,0,2704156,0,10400600,0,40116600,2,155117520},{0,2,0,6,0,20,0,70,0,252,0,924,0,3432,0,12870,0,48620,0,184756,0,705432,0,2704156,0,10400600,0,40116600,0,155117522}};
    /*for(n=3;n<=30;n++){
        printf("{");
        for(m=1;m<=30;m++){
        ans=0;
        dfs(1,0);
        m==30?printf("%d",ans):printf("%d,",ans);
        }
        printf("}");
    }*/
    cin>>n>>m;
    cout<<a[n-3][m-1]<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhoucheng_123/article/details/105602751