码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-10-12 20:52:38      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:模拟   比较不水的   

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

分析:观察得到:最中间是(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;
}


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

标签:模拟   比较不水的   

原文地址:http://blog.csdn.net/shengweisong/article/details/40020077

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!