題目
給你一個數n(n<=500),代表你需要構造一個n*n的矩陣,
該矩陣中,每個格子放上[1,n²]中的一個數,且每個數只能出現一次
把國際象棋中的車和皇后初始放在數字1所在的格子,
對於車(可橫豎走)和皇后(可橫豎斜走)來說,它們會按照以下的方案走:
①如果在車/皇后一步可達的範圍內,存在沒有走過的格子,就去這些格子中數值最小的那個格子
②如果不存在,就傳送到數值最小的格子,併產生1 vun的費用
然後繼續①操作,直至走完所有格子
你需要構造一個n*n的矩陣,
使得車產生的費用嚴格小於皇后產生的費用,輸出矩陣
思路來源
Roundgod代碼
題解
n=1和n=2顯然無解,因爲皇后根本不會產生費用
題目給了一個4*4的樣例,考慮到可以把4*4的值升到[n*n-15,n*n],
並從4*4的入口進入最後的4*4矩陣,n>4就可以做了
然而發現可以手玩一個3*3的矩陣,並把1固定在左上角,把3*3的矩陣固定在整個矩陣的右上角
遞歸求n-1,分奇偶,依次在外層添一道弧,
保證最終能進入原3*3的矩陣入口即可
代碼
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define sci(a) scanf("%d",&(a))
#define pb push_back
#define SZ(x) (int)(x.size())
const int N=510;
typedef vector<int> vec;
typedef vector<vec> mat;
mat a(3,vec(3));
int n;
mat dfs(int n){
if(n==3){
return a;
}
mat b=dfs(n-1),c(n,vec(n));
//讓b矩陣當c矩陣的右上角 且保持值最大
rep(i,0,n-2){
rep(j,1,n-1){
c[i][j]=b[i][j-1]+2*n-1;
}
}
int t=0;
if(n%2==0){
per(i,n-1,0){
c[n-1][i]=++t;
}
per(i,n-2,0){
c[i][0]=++t;
}
}
else{
rep(i,0,n-1){
c[i][0]=++t;
}
rep(i,1,n-1){
c[n-1][i]=++t;
}
}
return c;
}
int main(){
a[0][0]=1;a[0][1]=4;a[0][2]=5;
a[1][0]=7;a[1][1]=6;a[1][2]=9;
a[2][0]=8;a[2][1]=3;a[2][2]=2;
sci(n);
if(n<3){
puts("-1");
}
else{
mat ans=dfs(n);
rep(i,0,n-1){
rep(j,0,n-1){
printf("%d%c",ans[i][j]," \n"[j==n-1]);
}
}
}
return 0;
}