题目:
思路:
我在注释里面已经写得很明白了,注意枚举数字和判断越界
代码(答案:1580种):
#include
#include
#include
#include
#include
#include
#include
#include
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define N 1000+10
#define LL long long
using namespace std;
int map[10][10];
int vis[10];
int cnt;
int go[4][2]= {{0,-1},{-1,-1},{-1,0},{-1,1}};//因为是从左到右从上到下依次,所以只需要搜索下,左下,左,左上,上四个方向即可
int judge(int x,int y,int num)
{
for(int i=0;i<4;i++)
{
int xx=x+go[i][0];
int yy=y+go[i][1];
if(xx>=0&&xx<=2&&yy>=0&&yy<=3)//判断是否越界
{
if(map[xx][yy]==num-1||map[xx][yy]==num+1)//判断数字是否相邻
return 0;
}
}
return 1;
}
void dfs(int x,int y)
{
if(x==2&&y==3)//(2,3)点时结束点的位置
{
cnt++;
return;
}
if(y>3)//越界的时候,搜索下一层
{
dfs(x+1,0);
}
else
{
for(int i=0;i<=9;i++)//枚举要填的数
{
if(!vis[i]&&judge(x,y,i))
{
vis[i]=1;
map[x][y]=i;//填数
dfs(x,y+1);
map[x][y]=-100;//搜索完毕,取消标记
vis[i]=0;
}
}
}
}
int main()
{
for(int i=0; i<=2; i++)
for(int j=0; j<=3; j++)
map[i][j]=-100;//初始化一个最小值
cnt=0;
dfs(0,1);//因为(0,0)点没有,所以从(0,1)点搜索
cout<
2018年03月27日16:48:27重新写,可以枚举全排列,然后逐个判断是否符合条件
#include
using namespace std;
int go[8][2]= {0,1,1,0,0,-1,-1,0,1,1,-1,-1,-1,1,1,-1};
int e[5][5];
int num[15];
int judge(int x,int y)
{
if((x==1&&y==1)||(x==3&&y==4)) return 0;
if(x>=1&&x<=3&&y>=1&&y<=4) return 1;
return 0;
}
void init()
{
for(int i=0; i<=9; i++)
num[i]=i;
}
int abs(int a,int b)
{
if(a>b) return a-b;
return b-a;
}
int main()
{
int ans=0;
init();
do
{
int cnt=0;
for(int i=1; i<=3; i++)
{
for(int j=1; j<=4; j++)
{
if((i==1&&j==1)||(i==3&&j==4))continue;
e[i][j]=num[cnt++];
}
}
int flag=1;
for(int i=1; i<=3&&flag; i++)
{
for(int j=1; j<=4&&flag; j++)
{
if((i==1&&j==1)||(i==3&&j==4))
continue;
for(int k=0; k<8; k++)
{
int x=i+go[k][0];
int y=j+go[k][1];
if(judge(x,y)&&abs(e[x][y],e[i][j])==1)
{
flag=0;
break;
}
}
}
}
if(flag)ans++;
}
while(next_permutation(num,num+10));
printf("%d\n",ans);
return 0;
}