题目大意:给你一个n*n的方阵,填入1~n^2数字,使得方阵每个行的和,列的和,主对角线的和,副对角线的和均不相等,输出其中一种填法。
解题思路:目前只想到爆搜,TLE了。待补
代码如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef double db;
const int maxn=1001;
int image[maxn][maxn],n,flag,row[maxn];
void init();
bool judge(int ipt,int uipt);
void f(int x,int ipt,int uipt);
void dfs(int k,int x,int ipt,int uipt);
int main()
{
cin>>n;
flag=0;
memset(row,0,sizeof(row));
init();
f(1,0,0);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
printf("%d%c",image[i][j]," \n"[j==n]);
return 0;
}
void init()
{
int k=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++,k++)
{
row[i]+=k;
image[i][j]=k;
}
}
bool judge(int ipt,int uipt)
{
int i,temp[maxn];
for(i=1;i<=n;i++)
{
temp[i]=0;
for(int j=1;j<=n;j++)
temp[i]+=image[j][i];
if(ipt==temp[i] || uipt==temp[i] || ipt==row[i] || uipt==row[i])
return false;
}
sort(temp+1,temp+n+1);
for(i=1;i<n;i++)
if(temp[i]==temp[i+1])
return false;
/*
for(i=1;i<=n;i++)
if(temp[i]<=row[n] && temp[i]==row[lower_bound(row+1,row+n+1,temp[i])-row])
return false;
*/
for(i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(temp[i]==row[j])
return false;
return true;
}
void f(int x,int ipt,int uipt)
{
if(x>n)
{
if(ipt!=uipt && judge(ipt,uipt))
flag=1;
return ;
}
dfs(1,x,ipt,uipt);
return ;
}
void dfs(int k,int x,int ipt,int uipt)
{
if(k==n)
{
f(x+1,ipt+image[x][x],uipt+image[x][n-x+1]); //向下一层搜
return ;
}
int temp;
for(int i=k;i<n;i++)
{
temp=image[x][k];image[x][k]=image[x][i];image[x][i]=temp;
dfs(k+1,x,ipt,uipt);
if(flag)
return ;
temp=image[x][k];image[x][k]=image[x][i];image[x][i]=temp;
}
return ;
}
爆搜2,还是TLE了,这种会爆栈,一组都没过- -,哭 #include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
typedef double db;
const int maxn=1001;
int image[maxn][maxn],n,flag;
int Hang[maxn],Lie[maxn],vis[maxn*maxn];
bool judge()
{
int i,j,k;
int ipt=0,uipt=0;
for(i=k=1;i<=n;i++)
{
Hang[i]=Lie[i]=0;
for(j=1;j<=n;j++){
Hang[i]+=image[i][j];
Lie[i]+=image[j][i];
}
ipt+=image[i][i];
uipt+=image[i][n-i+1];
}
sort(Lie+1,Lie+1+n);
sort(Hang+1,Hang+1+n);
for(i=1;i<n;i++)
if(Lie[i]==Lie[i+1] || Hang[i]==Hang[i+1])
return false;
for(i=1;i<=n;i++)
{
if(Lie[i]==ipt || Lie[i]==uipt || Hang[i]==ipt || Hang[i]==uipt)
return false;
for(j=1;j<=n;j++)
if(Lie[i]==Hang[j])
return false;
}
return true;
}
void dfs(int x,int y)
{
if(x==n+1)
{
if(judge())
flag=1;
return ;
}
int k=n*n;
for(int i=1;i<=k;i++)
{
if(!vis[i])
{
vis[i]=1;
image[x][y]=i;
if(y==n)
dfs(x+1,1);
else
dfs(x,y+1);
if(flag)
return ;
vis[i]=0;
}
}
}
int main()
{
int i,j,t;
cin>>n;
flag=0;
memset(vis,0,sizeof(vis));
dfs(1,1);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
printf("%d%c",image[i][j]," \n"[j==n]);
return 0;
}