蓝桥杯 2016c/c++A组 方格填数

这篇博客探讨了两种不同的方法来解决棋盘上放置数字的问题,要求相邻数字差值为1。第一种方法使用深度优先搜索(DFS),初始化棋盘并递归填充数字,检查相邻格子的合法性。第二种方法通过数组排列组合,检查数组中相邻元素的差值,只有当所有相邻元素差值不为1时才增加计数。这两种方法都有效地计算了满足条件的解决方案数量。
摘要由CSDN通过智能技术生成

#include <iostream>
#include <cstdlib>
using namespace std;
int visit[10];//判断当前数字是否已经用过
int flag[3][4];//用来存储每个格子,判断格子是否能用
int map[3][4];//用来存储数字的格子
int ans;//记录数目
void init()//初始化
{
    ans=0;
    for(int i=0;i<10;i++)
      visit[i]=0;//全部初始化为0,代表没有用过
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<4;j++)
        {
            map[i][j]=0;
            flag[i][j]=1;//初始化为1,代表可以访问
        }
    }
    flag[0][0]=0;//左上角格子不能访问
    flag[2][3]=0;//右下角格子不能访问
}
void judge()
{
    int dct[8][2]=
    {
        -1,-1,//左上
        0,-1,//上
        1,-1,//右上
        -1,0,//左
        1,0,//右
        -1,1,//左下
        0,1,//下
        1,1,//右下
    };
    int list=1;
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<4;j++)
        {
            if(flag[i][j]==0)
               continue;
            for(int k=0;k<8;k++)//依次检查当前格子的八个方向
            {
                int x=j+dct[k][0];
                int y=i+dct[k][1];
                if(x<0||x>=4||y<0||y>=3||flag[y][x]==0)
                  continue;
                if(abs(map[i][j]-map[y][x]==1))
                   list=0;
            }
        }
    }
    if(list)
      ans++;
}
void dfs(int n)//表示第n次填入数据
{
    int x=n%4;//获取格子的横坐标
    int y=n/4;//获取格子的列坐标
    if(y==3)//表示填满数字了
    {
        judge();
        return;
    }
    if(flag[y][x])//当前格子可以访问时
    {
        for(int i=0;i<10;i++)
        {
            if(visit[i]==0)//如果数字i没有用过
            {
                visit[i]=1;
                map[y][x]=i;
                dfs(n+1);
                visit[i]=0;
            }
        }
    }
    else
    {
        dfs(n+1);//不可访问时,直接往下一个位置走
    }
}
int main()
{
    init();
    dfs(0);
    cout<<ans<<endl;
    system("pause");
    return 0;
}
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
int ans=0;
int a[10]={0,1,2,3,4,5,6,7,8,9};
int check()
{
    if(abs(a[0]-a[1])==1||abs(a[0]-a[3])==1||abs(a[0]-a[4])==1||abs(a[0]-a[5])==1)
      return 0;
    if(abs(a[1]-a[2])==1||abs(a[1]-a[4])==1||abs(a[1]-a[6])==1||abs(a[1]-a[5])==1)
      return 0;
    if(abs(a[2]-a[5])==1||abs(a[2]-a[6])==1)
      return 0;
    if(abs(a[3]-a[4])==1||abs(a[3]-a[7])==1||abs(a[3]-a[8])==1)
      return 0;
    if(abs(a[4]-a[5])==1||abs(a[4]-a[8])==1||abs(a[4]-a[7])==1||abs(a[4]-a[9])==1)
      return 0;
    if(abs(a[5]-a[6])==1||abs(a[5]-a[8])==1||abs(a[5]-a[9])==1)
      return 0;
    if(abs(a[6]-a[9])==1)
      return 0;
    if(abs(a[7]-a[8])==1)
      return 0;
    if(abs(a[8]-a[9])==1)
      return 0;
    return 1;
}
void ade(int begin,int end,int a[])
{
    if(begin==end)
    {
        if(check())
          ans++;
    }
    else 
    {
        for(int i=begin;i<=end;i++)
        {
            swap(a[end],a[i]);
            ade(begin,end-1,a);
            swap(a[end],a[i]);
        }
    }
}
int main()
{
    ade(0,9,a);
    cout<<ans<<endl;      
   system("pause");
   return 0;
}

上面两种方法都可以

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值