样例:输入2
样例:输出
1 2 3 4
2 1 4 3
3 4 1 1
4 3 2 1
其实这道题可以打个表,因为数据范围确实有点小,一共才五种情况
刚开始呢,我想要模拟来着,也是可以的,可以用到数独的思想
每行不能有重复的,每列不能有重复的
这个跟数独不一样的是,没有九宫格,所以搜索起来能简单点
我在这里呢,就用这种方法写一下
因为网上有大佬用分治算法了,我就另辟蹊径了
直接暴力模拟一下
因为时间效率过得去,我就写了一种及其笨拙但是很能让新手看懂的(因为我也是新手)
#include<bits/stdc++.h>
using namespace std;
int m;
int n;
int ok=0;
int a[50][50];
int lie[50][50];
int hang[50][50];
void print()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) cout<<a[i][j]<<" ";
cout<<endl;
}
}//输出函数
void dfs(int x,int y)
{
if(ok==1) return;
if(x==n+1)
{
print();
ok=1;
return;
}
if(y==n+1)
{
dfs(x+1,1);
return;
}
if(a[x][y]!=-1)
{
dfs(x,y+1);
return;
}
for(int i=1;i<=n;i++)
{
if(hang[x][i]==0&&lie[y][i]==0)
{
hang[x][i]=1;
lie[y][i]=1;
a[x][y]=i;
dfs(x,y+1);
hang[x][i]=0;
lie[y][i]=0;
a[x][y]=-1;
}//里面需要有个回溯算法的东西,因为第一遍穷举不可能完全就是正确答案,所以设上标记后需要释放标记
}
}
int main()
{
cin>>m;
n=pow(2,m);//偷个懒,直接调用pow函数求幂
memset(a,-1,sizeof(a));
for(int i=1;i<=n;i++)
{
a[1][i]=i;//第一个人已经安排ok了
a[i][1]=i;//第一列的人填上
}
for(int i=1;i<=n;i++)
{
a[i][n]=n-i+1;//每行最后一个
a[n][i]=n-i+1;//最后一行每一列
}
for(int i=n;i>=2;i--)
{
int temp=a[n][i];
a[temp][i]=n;
}//序号为1和序号为n的特殊处理一下就行
memset(hang,0,sizeof(hang));
memset(lie,0,sizeof(lie));//这两个数组相当于是标记数组,所以初始化
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]==-1) continue;
hang[i][a[i][j]]=1;
lie[j][a[i][j]]=1;
}
}
dfs(1,1);
return 0;
}