题目描述
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
输出方案总数即可。
开始题意理解错了,以为每个数字用的次数不限,错了,是每个数字只用一次
方一:
#include<stdio.h>
#include<math.h>
#include<string.h>
struct Direction{
int x;
int y;
};
struct Direction d[4]={{0,-1},{-1,-1},{-1,0},{-1,1}};//只检查这四个方向,别的四个方向还没有填数
int a[5][6],vis[11],sum=0;
judge(int k,int i,int j){
int l;
for(l=0;l<4;l++){
if(abs(k-a[i+d[l].x][j+d[l].y])==1) return 0;
}
return 1;
}
dfs(int l,int n){//一次确定一个位置可能填的数字
int i,j,k;
if(l==n){
sum++;
return 0;
}
else{
for(i=1;i<4;i++){
for(j=1;j<5;j++){
if(a[i][j]!=-2)continue;
for(k=0;k<=9;k++){
if(vis[k]==0&&judge(k,i,j)==1){
a[i][j]=k;
vis[k]=1;
dfs(l+1,n);//继续填下一个空格
//将该位置还原,该位置还可能放别的数
a[i][j]=-2;
vis[k]=0;
}
}
return 0;//这里很重要,如果不返回,则接下来就去别的空格了,而每一次只填一个空格,就乱了
}
}
}
}
int main(){
int i,j,k;
memset(vis,0,sizeof(vis));
for(i=0;i<5;i++){
for(j=0;j<6;j++){
if(i==0||j==0||i==4||j==5){
a[i][j]=-3;
}
else a[i][j]=-2;
}
}
a[1][1]=-3;a[3][4]=-3;
dfs(0,10);
printf("%d",sum);
return 0;
}
方二:
#include<stdio.h>
#include<string.h>
#include<math.h>
int a[5][6],res=0,vis[10];
struct D{
int x;
int y;
};
struct D d[4]={{0,-1},{-1,-1},{-1,0},{-1,1}};//判断这四个方向上是否有相邻的数字
int jugde(int k,int i,int j){
int l;
for(l=0;l<4;l++){//判断这四个方向上是否有相邻的数字
if(abs(k-a[i+d[l].x][j+d[l].y])==1) return 0;
}
return 1;
}
int dfs(int i,int j){
int k;
if(i==3&&j==4){//能到这个方格方案数就加1
res++;
return 0;
}
else{
if(j==5){//一行的空格填完填下一行
dfs(i+1,1);
}
else{
for(k=0;k<10;k++){
if(vis[k]==0&&jugde(k,i,j)==1){
a[i][j]=k;
vis[k]=1;
dfs(i,j+1);//继续填下一个位置
//将该空格还原,该空格还可能放别的数
vis[k]=0;
a[i][j]=-1;
}
}
}
}
}
int main(){
int i,j,k;
for(i=0;i<5;i++){
for(j=0;j<6;j++){
if(i==0||j==0||i==4||j==5){
a[i][j]=-2;
}
else a[i][j]=-1;
}
}
a[1][1]=-2;a[3][4]=-2;
dfs(1,2);
printf("%d",res);
}