题目链接:http://codevs.cn/problem/1160/
题目描述 Description
小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1开始以逆时针方向绕行,逐圈扩大,直到n行n列填满数字,请输出该n行n列正方形矩阵以及其的对角线数字之和.
输入描述 Input Description
n(即n行n列)
输出描述 Output Description
n+1行,n行为组成的矩阵,最后一行为对角线数字之和
样例输入 Sample Input
3
样例输出 Sample Output
5 4 3
6 1 2
7 8 9
25
<算法竞赛入门经典>一书中有一道类似的题目:
在n*n方陈里填入1,2,...,n*n,要求填成蛇形。例如n=4时方陈为:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
解法:参照http://blog.csdn.net/todd911/article/details/7926042
写的非常详细,我也是看完才写出这道题,刚开始写还把题目理解错了。
上面的解法思想就是分步判断。
外循环以圈数做循环,内部分为4并列循环,分别填充4条边。
借鉴这个解法:本题,从内向外。一个循环,填充一圈
#include <iostream> #include <vector> using namespace std; int main(){ int n =3; cin >> n; int r = n / 2;//圈数 int index = 1;//数字,内循环一次++,作为要填充的值; //int m[3][3] = { 0 };//例:m[3][5] 表示3行5列。 vector<vector<int> > m(n);//v为容器的容器,作为横列rows. for (int i = 0; i<n; i++) m[i].resize(n);//里层容器大小设置为纵列cols int x = n / 2;//纵列cols int y = n / 2;//横列rows m[x][y] = 1; //填充中心。题目范围已给定,n为奇数。 //开始填充矩阵 for (int i = 0; i < r; i++)//一圈一圈的循环 { int a = 2 * i + 1; int b = 1 + 2 * (i + 1); int start = a * a;//每圈开始值 i = 1,start = 9 int end = b * b;//每圈结束值 i = 1,end = 25 int slide = 2 * (i + 1) + 1; for (int k = 0; k < end - start; k++) { index++; if (k == 0){ x++; } if (k < slide - 1 && k >0){//1. y--; } else if (k < 2 * slide - 2 && k >0){//2. x--; } else if (k < 3 * slide - 3 && k >0){//3. y++; } else if (k < 4 * slide - 4 && k >0){//4. x++; } m[y][x] = index; } }// 外循环 //开始计算对角线之和 int sum = 0; for (int j = 0; j < n; j++) { sum += m[j][j] + m[n - j - 1][j];//前一个为正对角线,后一个为邪对角线。+1重叠了,最后要 -1 } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << m[i][j] << " "; } cout << ‘\n‘; } sum--; cout << sum; //system("pause"); return 0; }
写的不够好的地方,还望指正 :)
时间: 2024-12-20 10:10:36