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; }