方格填数

来源:互联网 发布:nba2k17捏脸数据分享 编辑:程序博客网 时间:2024/04/30 13:47

1160: 方格填数

时间限制: 1 Sec  内存限制: 128 MB
提交: 74  解决: 35
[提交][状态][讨论版]

题目描述

如上面的10个格子,填入0~9的数字,不能重复(原先已经填了一部分数字),要求:连续的两个数字不能相邻(左右,上下,对角都算相邻)。例如:数字0和1不能放在一起。
问:一共有多少种可能的填数方案?

输入

输入多组测试数据。
每组测试数据有三行,第一行三个整数,第二行四个整数,第三行三个整数,之间用空格隔开,分别代表每个空格所填的数,如果原先没有数,则填-1。
输入数据保证不重复数字,不保证连续数字不相邻。

输出

每组测试数据输出一行。
输出表示方案数目的整数。

样例输入

-1 -1 -1
-1 -1 -1 -1
-1 -1 -1
0 1 -1
-1 -1 -1 -1
-1 -1 -1
1 3 5
-1 -1 -1 -1
-1 -1 -1

样例输出

1580
0
8

思路:首先明确这是一道搜索的题目,那么就需要标记,由于每个数字只能用一次,定义b[10]作为标记数字0-9是否已经填入了,首先可以将这个矩阵补全,看做为一个3*4的矩阵,将第一个和最后一个用作别的数字进行代替,然后用for()输入数组,接下来就是对数组进行遍历,b[a[][]]=1对用过的数字进行标记,然后判定条件填数
代码如下:

//方格填数#include <stdio.h>#include <string.h>#include <stdlib.h>using namespace std;int a[4][5],b[10],count;int fun1(int i,int j,int k){if(j>0&&abs(k-a[i][j-1])==1)//判断所填数字左面是否满足条件; {return 0;}if(i>0&&abs(k-a[i-1][j])==1)//判断数字上面是否满足条件 {return 0;}if(i>0&&j>0&&abs(k-a[i-1][j-1])==1)//判断左上 {return 0;}if(i>0&&j<3&&abs(k-a[i-1][j+1])==1)//判断右上; {return 0;}    return 1;}void fun(int x){int i,j;int n=x/4;int m=x%4;if(x==11){count++;return;}if(a[n][m]==-1){for(i=0;i<=9;i++)/{    if(!b[i]&&fun1(n,m,i))//判断i这个数字是否用过,同时满足相邻、斜线数字绝对值不为一;     {a[n][m]=i;//填数字 b[i]=1;//标记i已经用过 fun(x+1);a[n][m]=-1;//回溯 b[i]=0;    }}}else if(fun1(n,m,a[n][m]))//判断已经填入的数字书否满足条件 {    fun(x+1);}}int main(){while(scanf("%d",&a[0][1])!=EOF){int i,j;count=0;memset(b,0,sizeof(b));//对b数组进行初始化         for(i=0,j=2;j<4;j++){scanf("%d",&a[i][j]);    }for(i=1,j=0;j<4;j++){scanf("%d",&a[i][j]);}for(i=2,j=0;j<3;j++){scanf("%d",&a[i][j]);}a[0][0]=-3;//将第一个和最后一个用其他小鱼-1的数字代替; a[2][3]=-3;for(i=0;i<3;i++){for(j=0;j<4;j++){    if(a[i][j]>=0)    {        b[a[i][j]]=1;//遍历a[][],并标记已经使用过的数字;     }}}fun(1);printf("%d\n",count);}return 0;}   



0 0
原创粉丝点击