2016蓝桥杯C/C++省赛 方格填数(深搜DFS)

题目:

2016蓝桥杯C/C++省赛 方格填数(深搜DFS)_第1张图片

思路:

我在注释里面已经写得很明白了,注意枚举数字和判断越界

代码(答案:1580种):

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define N 1000+10
#define LL long long
using namespace std;
int map[10][10];
int vis[10];
int cnt;
int go[4][2]= {{0,-1},{-1,-1},{-1,0},{-1,1}};//因为是从左到右从上到下依次,所以只需要搜索下,左下,左,左上,上四个方向即可
int judge(int x,int y,int num)
{
    for(int i=0;i<4;i++)
    {
        int xx=x+go[i][0];
        int yy=y+go[i][1];
        if(xx>=0&&xx<=2&&yy>=0&&yy<=3)//判断是否越界
        {
            if(map[xx][yy]==num-1||map[xx][yy]==num+1)//判断数字是否相邻
                return 0;
        }
    }
    return 1;
}
void dfs(int x,int y)
{
    if(x==2&&y==3)//(2,3)点时结束点的位置
    {
        cnt++;
        return;
    }
    if(y>3)//越界的时候,搜索下一层
    {
        dfs(x+1,0);
    }
    else
    {
        for(int i=0;i<=9;i++)//枚举要填的数
        {
            if(!vis[i]&&judge(x,y,i))
            {
                vis[i]=1;
                map[x][y]=i;//填数
                dfs(x,y+1);
                map[x][y]=-100;//搜索完毕,取消标记
                vis[i]=0;
            }
        }
    }
}
int main()
{
    for(int i=0; i<=2; i++)
        for(int j=0; j<=3; j++)
            map[i][j]=-100;//初始化一个最小值
    cnt=0;
    dfs(0,1);//因为(0,0)点没有,所以从(0,1)点搜索
    cout<

2018年03月27日16:48:27重新写,可以枚举全排列,然后逐个判断是否符合条件

#include 
using namespace std;
int go[8][2]= {0,1,1,0,0,-1,-1,0,1,1,-1,-1,-1,1,1,-1};
int e[5][5];
int num[15];
int judge(int x,int y)
{
    if((x==1&&y==1)||(x==3&&y==4)) return 0;
    if(x>=1&&x<=3&&y>=1&&y<=4) return 1;
    return 0;
}
void init()
{
    for(int i=0; i<=9; i++)
        num[i]=i;
}
int abs(int a,int b)
{
    if(a>b) return a-b;
    return b-a;
}
int main()
{
    int ans=0;
    init();
    do
    {
        int cnt=0;
        for(int i=1; i<=3; i++)
        {
            for(int j=1; j<=4; j++)
            {
                if((i==1&&j==1)||(i==3&&j==4))continue;
                e[i][j]=num[cnt++];
            }
        }
        int flag=1;
        for(int i=1; i<=3&&flag; i++)
        {
            for(int j=1; j<=4&&flag; j++)
            {
                if((i==1&&j==1)||(i==3&&j==4))
                    continue;
                for(int k=0; k<8; k++)
                {
                    int x=i+go[k][0];
                    int y=j+go[k][1];
                    if(judge(x,y)&&abs(e[x][y],e[i][j])==1)
                    {
                        flag=0;
                        break;
                    }
                }
            }
        }
        if(flag)ans++;
    }
    while(next_permutation(num,num+10));
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(【搜索(DFS/BFS)】,【蓝桥杯】)