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


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值