如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 …
3 5 8 14 …
4 9 13 …
10 12 …
11 …
…
容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。
本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分
思路
我们讨论 n n n行 n n n列位置上的数,可以发现要求这个 ( n , n ) (n,n) (n,n),可以通过求 p 1 p1 p1和 p 2 p2 p2,计算它们的平均数。 p 1 p1 p1是 n n n阶三角形的最大一个数, p 2 p2 p2是 n − 1 n-1 n−1阶三角形的最大一个数再加上1。
a n s w e r = ( f ( m ) + f ( m − 1 ) + 1 ) / 2 answer=(f(m)+f(m-1)+1)/2 answer=(f(m)+f(m−1)+1)/2
而 p 1 > p 2 p1>p2 p1>p2,且 p 1 p1 p1和 p 2 p2 p2都可通过计算三角形底边 m m m得到。从1开始累加到 m m m即可得到 n n n阶三角形中最大的数字。于是先计算底边 m m m。
f ( x ) = x ∗ ( x + 1 ) / 2 f(x)=x*(x+1)/2 f(x)=x∗(x+1)/2
不是每个三角形的底边都穿过 n n n行 n n n列,而是隔一个三角形才出现一个,由此出现线性关系 2 n 2n 2n。三角形最长的边为 m m m,代入 n = 2 n=2 n=2时, m = 5 m=5 m=5,由此有:
m = 2 n − 1 m=2n-1 m=2n−1
代码
#include<iostream>
using namespace std;
//计算从1累加到x的值
int f(int x){
return x*(x+1)/2;
}
int main(){
int n;
while(1){
cin>>n;
//计算三角形的底边
int m=2*n-1;
//大三角形+小三角形加一,两数取平均数
cout<<((f(m)+f(m-1)+1)/2)<<endl;
}
system("pause");
return 0;
}
练习题:蛇形填数
如下图所示,小明用从1 开始的正整数“蛇形”填充无限大的矩阵。
容易看出矩阵第二行第二列中的数是5。请你计算矩阵中第20 行第20 列的数是多少?
以下程序实现了这一功能,请你补全以下空白处内容:
提示:
当到达边界时,判断它应该向右走还是向下走,向右走完就直接向左下走,向下走完就直接向右上走
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i = 0;
int j = 0;
int cnt = 2;
int a[250][250];
a[0][0] = 1;
while (cnt < 1000)
{
j++;
while (i != -1 && j != -1)
{
a[i][j] = cnt++;
if (j == 0)
break;
i++;
j--;
}
i++;
while (i != -1 && j != -1)
{
___________;
}
}
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 20; j++)
{
cout << setw(5) << a[i][j] << ' ';
}
cout << '\n';
}
cout << a[19][19];
return 0;
}
A | a[i][j] = cnt++; if (i == 0) break; i++; j++; |
B | a[i][j] = cnt++; if (i == 0) break; i++; j--; |
C | a[i][j] = cnt++; if (i == 0) break; i--; j--; |
D | a[i][j] = cnt++; if (i == 0) break; i--; j++; |
答案:
a[i][j] = cnt++;
if (i == 0)
break;
i--;
j++;