洛谷P2615[NOIP2015 提高组] 神奇的幻方

一.链接及题目

P2615 [NOIP2015 提高组] 神奇的幻方

二.分析

读完题目后可以分析出来这道题基本解法就是模拟,数据范围不大,应当是不会超时。

第一个要处理的问题是查找数字k-1的问题,对于这种固定的问题,一般的处理方法是写一个函数,这里我们命名为find(),只需要对我们新建的“地图”进行遍历,找到即可停止。

第二个要处理的问题是填写数字k的问题,既然题目上对填写要求分了四种情况,那么我们就可以单独写一个函数去处理填写的问题,分别对下一个数字要填写的位置进行更新,这里我们将变量命名为stuffi,stuffj。

第三个要处理的问题是细节问题,为了方便理解和书写,我们只用到了二维数组里面索引为大于等于1的部分,经过分析推导可以得到,当输入一个奇数n时,数字1根据规则一定会填写到[1][n/2+1]另外还需要规定边界,以免遍历的过程中越界。

三.代码

#include <iostream>
#include <cmath>
#include <cstdio>

const int M=50;
using namespace std;
int n,rb,downb; //rb代表右边界,downb代表下边界
int map[M][M]; //初始地图
int stuffi,stuffj; //填充数字K的位置

void calculate(int ii,int jj){
	stuffi=stuffj=0; //初始化
	if(ii==1&&jj!=n){ //若k-1在第一行但不在最后一列
		stuffi=n;
		stuffj=jj+1;
		return;
	}else if(jj==n&&ii!=1){ //若k-1在最后一列但不在第一行
		stuffi=ii-1;
		stuffj=1;
		return;
	}else if(ii==1&&jj==n){ //若k-1在第一行最后一列
		stuffi=2;
		stuffj=jj;
		return;
	}else if(ii!=1&&jj!=n){ //若k-1既不在第一行,也不在最后一列
		if(map[ii-1][jj+1]==0&&ii-1>0&&jj+1<=n){ //未填数
			stuffi=ii-1;
			stuffj=jj+1;
			return;
		}else{ //填数
			stuffi=ii+1;
			stuffj=jj;
			return;
		}
	}
	return;
}

void find(int x){
	for(int i=1;i<=downb;i++){ //对map进行遍历,查找K-1所在的位置
		for(int j=1;j<=rb;j++){
			if(map[i][j]==x){
				calculate(i,j); //找到后进行计算判断
				return;
			}
		}
	}
}

int main(){
	cin>>n;
	rb=n; //规定边界
	downb=n; //规定边界
	map[1][n/2+1]=1; //填写数字1
	for(int k=2;k<=n*n;k++){
		find(k-1); //查找数字K-1
		map[stuffi][stuffj]=k;
	}
	//输出
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++) cout<<map[i][j]<<" ";
		cout<<endl;
	}
	return 0;
}

此解法并不是最优解,但适合初学者理解,感谢理解!

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值