第七届蓝桥杯第6题:方格填数



方格填数


如下的10个格子
   +--+--+--+
   |  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |
+--+--+--+


(如果显示有问题,也可以参看【图1.jpg】)


填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)


一共有多少种可能的填数方案?


请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。


我比赛的时候做的是:

错误答案:520
错误分析:10格子用一维数组记录,在筛选的时候忽略了处于左边界和右边界的格子的方向判断有限制,比赛的时候应该以快速高效率解答为目标,这个题用这种方式浪费了很多时间


正确答案:1580
完整代码:

#include <stdio.h>
#include <stdlib.h>


int ans = 0;


void Print(int a[])
{
	printf("   %2d %2d %2d\n", a[1], a[2], a[3]);
	printf("%2d %2d %2d %2d\n", a[4], a[5], a[6], a[7]);
	printf("%2d %2d %2d\n\n", a[8], a[9], a[10]);
}


//判断数组a中不存在数key 
int IsNoHave(int a[], int n, int key)
{
	for(int i = 1; i < n; i ++)
		if(a[i] == key)
			return 0;
	return 1;
}


int Check(int a[], int n, int k)
{
	static int d[] = {-1, -5, -4, -3}, di;
	
	if(4 == k || 8 == k){
		for(di = 2; di < 4; di ++)
			if( k + d[di] >= 1 && 1 == abs(a[k] - a[k + d[di]]) )
				return 0;
	}
	else if(3 == k || 7 == k){
		for(di = 0; di < 3; di ++)
			if( k + d[di] >= 1 && 1 == abs(a[k] - a[k + d[di]]) )
				return 0;
	}
	else{
		for(di = 0; di < 4; di ++)
			if( k + d[di] >= 1 && 1 == abs(a[k] - a[k + d[di]]) )
				return 0;
	}


	return 1;
}


void dfs(int a[], int k)
{
	if(11 == k){
		ans ++;
		//Print(a);
	}


	for(int num = 0; num <= 9; num ++)
		if(IsNoHave(a, k, num))
		{
			a[k] = num;
		 	if(Check(a, k, k))
				dfs(a, k + 1);
		}
}


int main()
{
	int a[11] = {-20};
	dfs(a, 1);
	printf("%d", ans);
	return 0;
}


第二种方法,使用二位数组:

#include <stdio.h>
#include <stdlib.h>


int ans = 0, flag[10] = {0};


int Check(int a[][4], int x, int y)
{
	static int dx[] = {0, -1, -1, -1}, dy[] = {-1, -1, 0, 1};
	
	for(int i = 0; i < 4; i ++)
		if( (x + dx[i] >= 0 && x + dx[i] < 3) && (y + dy[i] >= 0 && y + dy[i] < 4) )
		{
			if( 1 == abs(a[x][y] - a[ x + dx[i] ][ y + dy[i] ]))
				return 0;
		}


	return 1;
}


void dfs(int a[][4], int x, int y)
{
	if(2 == x && 3 == y){
		ans ++;
		return ;
	}
	
	for(int num = 0; num <= 9; num ++)
		if(!flag[num]){
			a[x][y] = num;
			flag[num] = 1;
			
			if(Check(a, x, y)){
				if(y + 1 < 4)
					dfs(a, x, y + 1);
				else
					dfs(a, x + 1, 0);
			}
			flag[num] = 0;
		}
}


int main()
{
	int a[3][4] = {-20};
	dfs(a, 0, 1);
	printf("%d", ans);
	return 0;
}

展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值