递归+DFS(入门) [Cloned]

递归+DFS(入门) [Cloned]

专题链接:https://vjudge.net/contest/343391#overview
A - 超级楼梯
原题链接:https://vjudge.net/problem/27332/origin
完整代码:

#include<stdio.h>
int f(int n)
{
    int m[45]={0,1,1};
    int i;
    for(i=3;i<=n;i++)
    {
        m[i]=m[i-1]+m[i-2];
    }
    return m[n];
}
int main()
{
    int T,x;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&x);
        printf("%d\n",f(x));
    }
    return 0;
}

B - 汉诺塔问题(Hanoi)
原题链接:http://bailian.openjudge.cn/practice/4147?lang=en_US
https://vjudge.net/problem/OpenJ_Bailian-4147
完整代码:

#include<stdio.h>
void hanoi(int n,char A,char B,char C)
{
    if(n==1){
        printf("%d:%c->%c\n",n,A,C);
    }
    else{
        hanoi(n-1,A,C,B);
        printf("%d:%c->%c\n",n,A,C);
        hanoi(n-1,B,A,C);
    }
}
int main()
{
    int n;
    char a,b,c;
    scanf("%d",&n);
    getchar();
    scanf("%c %c %c",&a,&b,&c);
    hanoi(n,a,b,c);
    return 0;
}

C - Prime Ring Problem
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1016
完整代码:

#include<stdio.h>
#include<math.h>
bool b[1010];    //定义一个数组用来存是否为素数,因为bool只有0和1所以定义bool,当然int型也可以
int ii;
int total;
int a[101];
//判断函数
//pd就是判断的意思,定位bool型和数组b的原因一样
bool pd(int x,int y)    //判断是否为素数
{
    int k,e;
    e=x+y;  //用e表示两个数相加,因为是两个数相加判断是否为素数
    for(k=2;k<=sqrt(e);k++)
    {
        if(e%k==0)
        {
            return 0;   //表示不是素数
        }
    }
    return 1;       //没有一个数可以整除,表示为素数,返回1
}
//打印函数
int print()
{
    total++;
    for(int j=1;j<=ii;j++)
    {
        if(a[1]==1&&j!=ii)
        {
             printf("%d ",a[j]);    //每个数要用空格隔开,但最后一个数直接换行,用一个if判断就行了。
        }                           //如果不这样会格式错误
       else if(a[1]==1&&j==ii)
       {
           printf("%d",a[j]);
       }
       else return 0;               //不retur会打印空行
    }
    printf("\n");
    //return 0;
    //因为定义的是int,所以要有返回值,但是对答案不影响,不打retur 0,答案不会错所以我注释掉了。
}
//递归
int search(int t)
{
    for(int i=1;i<=ii;i++)
    {
        if(pd(a[t-1],i)&&(!b[i]))
        {
            a[t]=i;
            b[i]=1;
            if(t==ii)
            {
                if(pd(a[ii],a[1]))print();  //判断+打印
            }
            else search(t+1);               //递归
            b[i]=0;     //把bool b从新赋值为0,这里是回溯的思想
        }
    }
   // return 0;
   //和上面的print函数的retur 0原因一样。
}
int main()
{
    int c=1;        //定义一个计数器,输出的时候让输出Case n:。
    while(~scanf("%d",&ii))     //多组输入
    {
        printf("Case %d:\n",c);
        search(1);
        printf("\n");       //题目要求每组后面多一个换行
        c++;        //每次输入完后计数器加一
    }
    return 0;
}

D - Oil Deposits
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1241
完整代码:

#include<stdio.h>
#include<string.h>
char map[110][110];//储存数据
int n,m;
//八个方位
int vis[8][2]={{-1,-1},{-1,0},{-1,1},{0,1},{0,-1},{1,1},{1,0},{1,-1}};
void dfs(int x,int y)   //深度优先搜索
{
    map[x][y]='*';//搜索过的@都变为*
    for(int i=0;i<8;i++)
    {
        //下一个点的坐标
        int dx=x+vis[i][0];
        int dy=y+vis[i][1];
        if(dx<0||dx>=n||dy<0||dy>=m)//判断是否越界
        {
            continue;
        }
        if(map[dx][dy]=='@')
        {
            dfs(dx,dy);//开始尝试下一个点
        }
    }
}
int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        memset(map,0,sizeof(map));
        if(m==0)
            break;
        for(int i=0;i<n;i++)
        {
            scanf("%s",map[i]);
        }
        int sum=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(map[i][j]=='@')//查找
                {
                    sum++;
                    dfs(i,j);
                }
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

E - 迷宫问题
原题链接:http://poj.org/problem?id=3984
完整代码:

#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
int dir[4][2] = { {1,0},  {-1,0}, {0,-1}, {0,1}};   //上下左右移动,四个方位
int num[5][5];  //储存数据
struct node
{
    int x, y;
}v[5][5];   //结构体数组(x,y)坐标
void DFS(int x, int y)  //深度优先搜索
{
    if(x == 0 && y ==0) //如果是起点(0,0)
    {
        return;
    }
    DFS(v[x][y].x, v[x][y].y);  //递归
    printf("(%d, %d)\n",v[x][y].x, v[x][y].y);  //打印坐标
}
void BFS(node s)    //广度优先搜索(s为坐标(结构体型变量))
{
    node t, q;      //定义两个结构体变量
    queue<node>Q;   //定义一个队列,用队列存数据
    Q.push(s);      //入队(把坐标存入队列)
    while(Q.size()) //如果队列不为空
    {
        q = Q.front();  //队首元素赋给q
        Q.pop();        //出列
        if(q.x == 4 && q.y == 4)    //坐标为终点
        {

            DFS(q.x, q.y);  //开始尝试下一个点
            printf("(%d, %d)\n",q.x,q.y);   //打印终点坐标
            return;
        }
        for(int i = 0; i<4; i++)
        {
            t = q;              //关键之笔,让同一个位置走四次不同的方向
            //计算下一点的坐标
            t.x += dir[i][0];
            t.y += dir[i][1];
            if(t.x >=0 && t.y >=0 && t.x <5 && t.y <5  && num[t.x][t.y] == 0)//判断是否越界,都在[5][5]之内,
            {                                                                //且不能是走过的路或者是墙。

                v[t.x][t.y].x = q.x;
                v[t.x][t.y].y = q.y;
                num[t.x][t.y] = 1;  //把走过的都变成墙(把0变成1)
                Q.push(t);  //入列
            }
        }
    }
}
int main(void)
{
    for(int i = 0; i<5; i++)
    {
        for(int j = 0; j<5; j++)
        {
            scanf("%d",&num[i][j]); //输入二维数组地图
        }
    }
    memset(v, 0, sizeof(v)); //清空数组
    node s; //定义一个结构体型的变量

    //初始化(x,y),坐标从(0,0)开始
    s.x = 0;
    s.y = 0;
    BFS(s); //调用BFS函数
    return 0;
}

F - Tempter of the Bone
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010
完整代码:

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

char Map[10][10];   //地图
int visit[10][10];  //储存数据
int n,m,t,endx,endy,flag;   //n、m、结束坐标、标记

void dfs(int startx,int starty,int time)    //开始坐标,时间
{
    int dx,dy;
    int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};  //上下左右四个方向
    if(flag)        //***很重要,可以减少步骤,如果直接找到路线就直接跳出
    {
        return;
    }
    if(startx==endx&&starty==endy&&time==t)
    {
        flag=1;
        return;
    }
    int temp=t-time-abs(endx-startx)-abs(endy-starty);  //剪枝代码
    if(temp<0||temp&1)  //如果剩余的步数已经不足以走到出口,且必须是偶数,偶数-偶数=偶数,奇数-奇数=偶数
    {
        return;
    }
    for(int i=0;i<4;i++)
    {
        dx=startx+dir[i][0];
        dy=starty+dir[i][1];
        if(dx<0||dy>=m||dy<0||dx>=n)
        {
            continue;
        }
        if(Map[dx][dy]!='X'&&visit[dx][dy]==0)
        {
            visit[dx][dy]=1;    //标记,判断能不能走
            dfs(dx,dy,time+1);
            if(flag)            //找到就return
                return;
            visit[dx][dy]=0;    //返回标记,方便下次寻找
        }
    }
    return ;
}

int main()
{
    int startx,starty,wall;     //开始坐标、墙
    while(cin>>n>>m>>t)
    {
        if(n==0&&m==0&&t==0)
        {
            break;
        }
        flag=0;wall=0;
        memset(visit,0,sizeof(visit));
        for(int i=0;i<n;i++)    //画地图
        {
            scanf("%s",Map[i]);
        }
        for(int i=0;i<n;i++)    //判断
        {
            for(int j=0;j<m;j++)
            {
                if(Map[i][j]=='S')
                {
                    startx=i;starty=j;
                }
                if(Map[i][j]=='D')
                {
                    endx=i;endy=j;
                }
                if(Map[i][j]=='X')
                {
                    wall++;
                }
            }
        }
        if(t>n*m-wall-1)        //判断时间与墙数和地图的关系
        {
            cout<<"NO"<<endl;
            continue;
        }
        visit[startx][starty]=1;    //标记走过的路线
        dfs(startx,starty,0);
        if(flag==1)
        {
            cout<<"YES"<<endl;
        }
        else
        {
            cout<<"NO"<<endl;
        }
    }
    return 0;
}
发布了42 篇原创文章 · 获赞 44 · 访问量 1790

猜你喜欢

转载自blog.csdn.net/qq_45856289/article/details/104212063