E. Road to 1600
题意:
车可以走直线,皇后可以走直线和对角线
玩家的起点在1号点,每次移动选择一个可以直接到达的没被访问的点,如果没有这样的点,可以花费一个代价传送到最小的没访问的点
直到所有点被访问
构造一种方案,使得车的花费严格小于皇后的花费
分析:
这题是看杜老师讲题写的
杜老师首先用暴力构造了一个3*3的可行方案,很巧妙
$$ egin{vmatrix}4&3 & 1\ 5 & 2 &8 \9 &6 &7 end{vmatrix} $$
对于$n$等于1或者2的情况,因为两两互达,所以车和皇后没有区别
对于$n$大于3的情况,我们可以把这个矩阵放在左上角,然后把矩阵之外的点走完并且入口刚好是矩阵的入口
例如$n=4$
$$egin{vmatrix}4&3 & 1&7 \ 5 & 2 & 8 &6 \ 9 & 6 & 7 & 5 \ 1 & 2 & 3 & 4 end{vmatrix}$$
AC代码:
#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=(b);i>=(a);i--)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef long long ll;
typedef vector<int> VI;
typedef pair<int,int> PII;
const ll mod=998244353 ;
const int maxn=500+7;
int ma[maxn][maxn];
int n;
int main() {
scanf("%d",&n);
if(n<=2){
printf("-1");
return 0;
}
int now=n*n;
int cnt=9;
ma[1][1]=6;
ma[1][2]=7;
ma[1][3]=9;
ma[2][1]=5;
ma[2][2]=8;
ma[2][3]=2;
ma[3][1]=1;
ma[3][2]=4;
ma[3][3]=3;
rep(i,4,n){
if(i%2==0){
rep(j,1,i)ma[j][i]=++cnt;
per(j,1,i-1)ma[i][j]=++cnt;
}else{
rep(j,1,i)ma[i][j]=++cnt;
per(j,1,i-1)ma[j][i]=++cnt;
}
}
rep(i,1,n){
rep(j,1,n){
printf("%d%c",n*n-ma[i][j]+1,"
"[j==n]);
}
}
return 0;
}