dfs (二进制枚举,暴力,马的管辖)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wwwlps/article/details/88593696

在中国象棋中,马是走日字的。一个马的管辖范围指的是当前位置以及一步之内能走到的位置,下图的绿色旗子表示马能走到的位置。

如果一匹马的某个方向被蹩马脚,它就不能往这个方向跳了,如下图所示,海星的位置存在旗子,马就不能往上跳到那两个位置了:

那么问题来了,在一个 n\times mn×m 的棋盘内,如何用最少的马管辖住所有 n\times mn×m 个格子。比如 n=m=3n=m=3 时,最少要用 55 只马才能管辖所有棋盘,一种可能的方案如下: 

当 n=m=5n=m=5 时,请你求出用最少马管辖的 方案个数

样例输入复制

样例输出复制

题目来源

2019 蓝桥杯省赛 B 组模拟赛(一)

题目解答:

用二进制2^25次方枚举所有马的摆放情况,对每一种情况,判断是否都管辖即可。注意细节。

扫描二维码关注公众号,回复: 5621221 查看本文章

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
#include <cstdio>
#include <map>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=6;
int n,m,len,sum,mini;
int mapp[maxn][maxn];
bool book[maxn][maxn];
int dx[4][2]={-2,-2,2,2,-1,1,-1,1};
int dy[4][2]={1,-1,1,-1,2,2,-2,-2};
int px[4]={-1,1,0,0};
int py[4]={0,0,1,-1};
bool check(int x,int y)
{
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
bool judge()
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(!book[i][j])
                return false;
        }
    }
    return true;
}
int main()
{
    n=m=5;
    len=n*m;
    sum=0;
    mini=2*len;
    for(int i=1;i<(1<<len);i++)
    {
        int cnt=0;
        memset(mapp,0,sizeof(mapp));
        memset(book,false,sizeof(book));
        int cnz=0;
        for(int j=i;j>0;j>>=1)
        {
            if(j&1)
            {
                mapp[cnt/5][cnt%5]=1;
                book[cnt/5][cnt%5]=true;
                cnz++;
            }
            cnt++;
        }
        if(cnz>mini)
            continue;
        for(int u=0;u<n;u++)
        {
            for(int v=0;v<m;v++)
            {
                if(mapp[u][v]==1)
                {
                    for(int z=0;z<4;z++)
                    {
                        int tx=u+px[z];
                        int ty=v+py[z];
                        if(check(tx,ty)&&mapp[tx][ty]==0)
                        {
                            for(int j=0;j<2;j++)
                            {
                                int zx=u+dx[z][j];
                                int zy=v+dy[z][j];
                                if(check(zx,zy)&&book[zx][zy]==false&&mapp[zx][zy]==0)
                                {
                                    book[zx][zy]=true;
                                }
                            }
                        }
                    }
                }
            }
        }
        if(judge())
        {
            if(cnz<mini)
            {
                mini=cnz;
                sum=1;
            }
            else if(cnz==mini)
            {
                sum++;
            }
        }
    }
    cout << mini << ' ' << sum << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wwwlps/article/details/88593696