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

比赛的时候花了一个多小时,以做不做

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

难点:模拟的时候数据有点杂,非常easy搞错,要细心点。

心得:做题的时候要先确定思路是正确的,而且要履好思路之后在写程序。

代码:

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


版权声明:本文博客原创文章。博客,未经同意,不得转载。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值