比赛的时候花了一个多小时还是没做出来
分析:观察得到:最中间是(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; }
原文地址:http://blog.csdn.net/shengweisong/article/details/40020077