Codeforces Round #632 (Div. 2) E.Road to 1600(思维题/构造 递归)

31 篇文章 0 订阅
15 篇文章 1 订阅

题目

给你一个数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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Code92007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值