基本思路:每行进行全排列,与前面的字典序全排列的一个不同就是这里的visited[][]数组要开成二维的,一个Visited[row][i]记录行里面的用过的数,另外一个Visited[i][col]用来记录列里面,确保无重复。同时,边界多了一种列到边界行没到的情况,这时候要继续traceback,只是列参数变为0,行参数+1。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int m, n;
int count=0;
int a[100][100];
int visited[100][100];
int visited1[100][100];
int ok(int i, int j)
{
int flag=1;
int x,y;
for(x=0;x<i;x++)
{
if(a[x][j]==a[i][j])
{
flag=0;
break;
}
}
for(y=0;y<j;y++)
{
if(a[i][y]==a[i][j])
{
flag=0;
break;
}
}
return flag;
}
void traceback(int x, int y)
{
if(x==m-1&&y==n)
{
// printf("wa\n");
count++;
return ;
}
else if(y==n)
{
traceback(x+1,0);
}
int i, j; int temp;
for(i=1;i<=n;i++)
{
if(!visited[x][i]&&!visited1[i][y])
{
visited[x][i]=1; visited1[i][y]=1;
traceback(x,y+1);
visited[x][i]=0; visited1[i][y]=0;
}
}
}
int main()
{
scanf("%d%d",&m,&n);
memset(visited,0,sizeof(visited));
memset(visited1,0,sizeof(visited1));
traceback(0,0);
printf("%d\n",count);
return 0;
}