第七届蓝桥杯 方格填数

博客讲述了在解决第七届蓝桥杯比赛中遇到的方格填数问题时,由于二维数组初始化不当导致的错误。作者通过使用-2来区分边界,-1来表示未填数值,解决了临近数判断的问题。此外,还提到了C++中`next_permutation`函数在解决此类问题时的高效性。
摘要由CSDN通过智能技术生成

     本来一道练手的题,却被坑死了  - - 

  有谁答案是65的举个手!(正确答案是1580  , 0-9不重复)


  原因在于---> 你的数组区分未填入的数是什么,我用的是二维数组

  初始化是这样的:

   int g[5][6]={{-1,-1,-1,-1,-1,-1},{-1,0,0,0,-1,-1}, {-1,0,0,0,0,-1},{-1,-1,0,0,0,-1}

                ,{-1,-1,-1,-1,-1,-1}}

   但是,你填数的时候在判断过程中是临近数不能相邻,那么一旦1与未填的内容0相比,就不能填这个1了!因此,会有少算很多情况!

   改成:

   int g[5][6]={{-2,-2,-2,-2,-2,-2},{-2,-1,-1,-1,-2,-2}, {-2,-1,-1,-1,-1,-2}, {-2,-2,-1,-1,-1,-2}

                 ,{-2,-2,-2,-2,-2,-2} };

   避免造成临近数的误会。(-2用于区分边界,-1用于区分未填的)


   DFS

   

#include<stdio.h>
int g[5][6]={{-2,-2,-2,-2,-2,-2},{-2,-1,-1,-1,-2,-2}, {-2,-1,-1,-1,-1,-2}, {-2,-2,-1,-1,-1,-2},{-2,-2,-2,-2,-2,-2} };
int count = 0;
int dx[]={0,0,1,-1,1,-1,1,-1};
int dy[]={1,-1,0,0,1,-1,-1,1};
int vis[11]={0,0,0,0,0,0,0,0,0,0,0} ;
int check(int n,int x,int y)
{
    for(int i = 0;i<8;i++)
	{
		if(n  == g[x+dx[i]][y+dy[i]]+1 || n == g[x+dx[i]][y+dy[i]]-1)
			return 0;
	}
	return 1; 
}
int dfs(int n, int c)
{
	int i,j, k;

	
	if(c == n-1)
	{	
	    count++;	
    	printf("%d\n",count);
	}	
    else
	{
	for(i = 1;i<4;i++)
	{
	    for(j = 1;j<5;j++)
		{
		    if(g[i][j]== -2 || g[i][j] != -1)continue; // || newx< 1 || newy< 1 || newx > 4 || newy >4
			
		    for(k = 1;k<n;k++)
			{
			   if(vis[k] == 0 && check(k,i,j) )
			   {
				vis[k] =1;
				g[i][j] = k;
				dfs(n,c+1);
				g[i][j] = -1;
                vis[k] =0;
			   }
			}
			return 0;
		}

	}

	}
	return 0;
	//printf("*");
}
int main()
{
    count = 0;  
    dfs(11,0);

   printf("%d",count);
   return 0;
}

   哎 ,看了别人的才发现一个问题,这种题应该用更快的方法才行,C++  中<algorithm>里提供了一个函数为

next_permutation(begin ,end); 直接提供排序,直接改变数祖的内容;

 

   具体算法请看 方格填数 next_permutation 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值