CodeVs 蛇形矩阵
题目链接: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;
}
写的不够好的地方,还望指正 :)