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

来源:互联网 发布:matlab 循环遍历数组 编辑:程序博客网 时间:2024/06/13 21:54

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

分析:观察得到:最中间是(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
原创粉丝点击