zoukankan      html  css  js  c++  java
  • poj 2488 A Knight's Journey 回溯

    /*
    
    题目:
        马能否从(1,1)开始走完所有的格点,并且所走的格点之前都没有走过
    
    分析:
        dfs+回溯,分8个方向走,用Next[i,j]记录位置(i,j)的下一位的所在位置
    
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    const int X = 30;
    
    int n,m;
    int Next[X][X];
    bool use[X][X];
    
    int dir[8][2]  = {{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};//方向偏移量,按字典序
    
    bool check(int x,int y) //检查边界以及是否已遍历
    {
        if(x<1||y<1||x>n||y>m)
            return false;
        if(use[x][y])
            return false;
        return true;
    }
    
    bool dfs(int x,int y,int cnt)   //位置(i,j),cnt表示已经遍历过的格子数
    {
        use[x][y] = true;
        if(cnt==n*m-1)  //全部遍历完
            return true;
        int cx,cy;
        for(int i=0;i<8;i++)
        {
            cx = x+dir[i][0];
            cy = y+dir[i][1];
            if(check(cx,cy))
            {
                Next[x][y] = cx*10+cy;
                use[cx][cy] = true;
                if(dfs(cx,cy,cnt+1))    //能一步走到头
                    return true;
                Next[x][y] = -1;    //回溯
                use[cx][cy] = false;
            }
        }
        return false;
    }
    
    void print(int x,int y) //递归打印路径
    {
        printf("%c%d",(char)(x+'A'-1),y);
        if(Next[x][y]!=-1)
        {
            int px = Next[x][y]/10;
            int py = Next[x][y]%10;
            print(px,py);
        }
    }
    
    int main()
    {
        freopen("sum.in","r",stdin);
        freopen("sum.out","w",stdout);
        int ncase;
        cin>>ncase;
        for(int N_case=1;N_case<=ncase;N_case++)
        {
            printf("Scenario #%d:\n",N_case);
            scanf("%d%d",&m,&n);
            memset(Next,-1,sizeof(Next));
            memset(use,false,sizeof(use));
            use[1][1] = true;
            dfs(1,1,0);
            bool flag = false;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    if(!use[i][j])
                        flag = true;
            if(flag)
            {
                printf("impossible\n\n");
                continue;
            }
            print(1,1);
            cout<<endl<<endl;
        }
    
        return 0;
    }
  • 相关阅读:
    CSS3 target伪类简介
    不用position,让div垂直居中
    css3 在线编辑工具 连兼容都写好了
    a标签伪类的顺序
    oncopy和onpaste
    【leetcode】1523. Count Odd Numbers in an Interval Range
    【leetcode】1518. Water Bottles
    【leetcode】1514. Path with Maximum Probability
    【leetcode】1513. Number of Substrings With Only 1s
    【leetcode】1512. Number of Good Pairs
  • 原文地址:https://www.cnblogs.com/yejinru/p/2521885.html
Copyright © 2011-2022 走看看