hdoj 2183 奇数阶魔方(II) 【模拟】+【规律】

比赛的时候花了一个多小时还是没做出来

分析:观察得到:最中间是(n*n+1)/2, 中间的上面是n*n,下面是1, 左边是n,右面是(n*n+1)-n,而且正对角线是最左上对到最右下端增加(+1),另外一条对角线是最右上到最左下递减(-n) ,其他对角线也是这样的规律。

难点:模拟的时候数据有点杂,很容易搞错,要细心点。

心得:做题的时候要先确定思路是正确的,并且要履好思路之后在敲代码。

代码:

#include <cstdio>
#include <cstring>
int s[25][25];
int n;
void leup(int x, int y){   //左上
	int i;
	i = 1;
	while(i < x&&i < y){
		s[x-i][y-i] = s[x-i+1][y-i+1]-1; ++i;
	}
}
void rido(int x, int y){ //右下
	int i = 1;
	while(x+i<=n&&y+i<=n){
		s[x+i][y+i] = s[x+i-1][y+i-1]+1; ++i;
	}
}
void riup(int x, int y){//右上
	int i = 1;
	while(x-i>0&&y+i<=n){
		s[x-i][y+i] = s[x-i+1][y+i-1]-n; ++i;
	}
}
void ledo(int x, int y){//左下
	int i = 1;
	while(x+i<=n&&y-i>0){
		s[x+i][y-i] = s[x+i-1][y-i+1]+n; ++i;
	}
}
int main(){
	int t;
	scanf("%d", &t);
	while(t --){
		scanf("%d", &n);
		int mid = n-n/2;
		s[mid][mid] = (n*n+1)/2;
		s[mid-1][mid] = n*n;
		s[mid+1][mid] = 1;
		s[mid][mid-1] = n;
		s[mid][mid+1] = (n*n+1)-n;
		leup(mid, mid);//对角线
		ledo(mid, mid);
		riup(mid, mid);
		rido(mid, mid);
		for(int i = 1; i < mid; ++i){  //垂直对角线上的点的线
			//leup(mid, mid);
			//ledo(mid, mid);
			riup(mid-i, mid-i);
			ledo(mid-i, mid-i);
			ledo(mid+i, mid+i);
			riup(mid+i, mid+i);
		}
			leup(mid, mid-1); //确定最接近对角线并且平行对角线的线
			ledo(mid, mid-1);
			rido(mid, mid+1);
			riup(mid, mid+1);

			leup(mid-1, mid);
			riup(mid-1, mid);
			rido(mid+1, mid);
			ledo(mid+1, mid);

		for(int i = 1; i < mid-1; ++i){ //垂直上面确定的线上的点的线
			ledo(mid-i, mid-1-i);
			riup(mid-1-i, mid-i);
			ledo(mid+1+i, mid+i);
			riup(mid+i-1, mid+i);
		}
		for(int i = 1; i <= n; ++ i){
			for(int j = 1; j <= n; ++j){
				printf("%4d", s[i][j]);
			}
			printf("\n");
		}
	}
	return 0;
}
时间: 2024-11-08 18:14:12

hdoj 2183 奇数阶魔方(II) 【模拟】+【规律】的相关文章

Hdu 1998 奇数阶魔方

奇数阶魔方 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4629    Accepted Submission(s): 2622 Problem Description 一个 n 阶方阵的元素是1,2,...,n^2,它的每行,每列和2条对角线上元素的和相等,这样的方阵叫魔方.n为奇数时我们有1种构造方法,叫做"右上方" ,

奇数阶魔方 NYOJ 734

#include<stdio.h>//奇数阶魔方(734) int main() { int a[20][20],i,j,n,x,cnt; scanf("%d",&x); while(x--){ scanf("%d",&n); for(i=0;i<n;i++){ for(j=0;j<n;j++){ a[i][j]=0; } } a[0][n/2]=1; i=0;j=n/2; cnt=1; while(cnt<=n*n){

算法:九宫格问题--奇数阶魔方(Magic-Square)

一.魔方介绍 魔方(这里是简称,也可以叫幻方.魔术矩阵,Magic Square)是 n×n 正方形网格(n 为每侧的单元数),里面每个单元格填充了不同的正整数 1, 2, 3, ... , n2,并且每一行.每一列和对角线中的正整数之和相等.每行.每列以及对角线上的单元格里的正整数之和又叫做魔术常数或魔方的魔术和. 幻方历史: <系辞>云:“河出图,洛出书,圣人则之.”在宋朝之前,洛书的记述只有文字. 九宫图实物最早发现于西汉,1977年中国考古学家在安徽阜阳县双古堆西汉古墓中发现汉文帝七年

奇数阶魔方问题

问题: 一个 n 阶方阵的元素是1,2,...,n^2,它的每行,每列和2条对角线上元素的和相等,这样的方阵叫魔方.n为奇数时我们有1种构造方法,叫做“右上方” ,例如下面给出n=3,5,7时的魔方.38 1 63 5 74 9 2517 24 1 8 1523 5 7 14 164 6 13 20 2210 12 19 21 311 18 25 2 9730 39 48 1 10 19 2838 47 7 9 18 27 2946 6 8 17 26 35 375 14 16 25 34 36

杭电ACM 1998奇数阶魔方

#include<stdio.h>#include <string.h>int main(){ int n,m; int a[40][40]={0}; scanf("%d",&n); while(n--) { scanf("%d",&m); int i; int j; memset(a,0,sizeof(a)); i=0; j=m/2; int k=1; while(k<=m*m) { if(i<0&&am

HDU ACM 1998奇数阶魔方

方法: 1.第一个数填第一行正中间. 2.以后依次往上一行后一列填,并遵循如下规则: a.如果往上超出第一行则往最后一行开始: b.如果往右超出最后一列则往第一列开始: c.右上角填后要往下一行开始,列不变: d.如果所要填数之前已填,则往他下面填. 3.循环第二步,直到方格填满. #include<iostream> using namespace std; int main() { int a[20][20]; int T,n,i,j,k; cin>>T; while(T--)

hdu1998 奇数阶魔法 (数组填数)

奇数阶魔方 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3071    Accepted Submission(s): 1614 Problem Description 一个 n 阶方阵的元素是1,2,...,n^2,它的每行,每列和2条对角线上元素的和相等,这样 的方阵叫魔方.n为奇数时我们有1种构造方法,叫做"右上方"

n阶魔方阵(奇数阵)的输出

需求 要求输出1~n2的自然数构成的魔方阵. STEP 1 什么是魔方阵? 魔方阵,古代又称"纵横图",是指组成元素为自然数1.2-n2的平方的n×n的方阵,其中每个元素值都不相等,且每行.每列以及主.副对角线上各n个元素之和都相等. STEP 2 魔方阵的规律是什么? 此处先写简单一点的奇阶魔方阵,偶数阶的算法更复杂,暂不讨论. 奇阶魔方阵的排列方法: ⑴将1放在第一行中间一列: ⑵从2开始直到n×n止各数依次按下列规则存放:每一个数存放的行比前一个数的行数减1,列数加1: ⑶如果上

任意阶魔方阵(幻方)的算法及C语言实现

写于2012.10: 本来这是谭浩强那本<C程序设计(第四版)>的一道课后习题,刚开始做得时候去网上找最优的算法,结果发现奇数和双偶数(4的倍数)的情况下算法都比较简单,但是单偶数(2的倍数但不是4的倍数)情况一直找不到明确的算法,就连百度百科对这一问题的解释也是“因非四的倍数作法相当复杂,在此只介绍四的倍数的作法”,而且连谭浩强那本书给的答案中竟然也变相的限定了n只能为奇数(题目并未说明).在广泛查找资料后,发现了一篇由中南大学信息科学与工程学院某教授和研究生撰写的论文,介绍了任意阶幻方的算