我正在寻找一种算法,它编号并输出一个边长为 n 的三角形(或正方形的一半),其中 n 是程序的输入。但是编号从三角形的顶部开始,沿着对角线向下,沿着底行向上,向上沿着左边缘。如果剩余内部,则从最高数字斜向下并继续。
以下是一个例子:
1
9 2
8 10 3
7 6 5 4
这是我的代码,结果是:
1
10 2
9 8 3
7 6 5 4
是否有任何算法用于此程序,如果有任何请向我解释。
上述程序适用于行大小小于3
但不大于3
的大小。
#include<iostream.h>
#include<conio.h>
void main()
{
int n,i,j,v=0;
static int k;
clrscr();
cout<<"Enter the number of rows : ";
cin>>n;
for(i=0;i<n;i++)
{
for(j=0;j<=i;j++)
{
v++;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<i;j++)
{
cout<<v;
cout<<"\t";
v--;
}
while(k==i)
{
k++;
cout<<k;
cout<<"\t";
}
cout<<"\n";
}
getch();
}
答案 0 :(得分:3)
这是一个不使用任何阵列存储的解决方案。螺旋可以被认为是彼此内部的一组直角三角形。该函数迭代所有行和列,并且对于每个位置,它通过找到到外三角形边缘的最近距离来计算元素所在的三角形,然后计算其相对于顶部的调整位置(x,y) - 该内三角的左角,内三角的行数(r)和内三角的起始编号(start + 1)。然后它根据它是否位于对角线,水平或垂直方向输出一个数字。
#include <iostream>
#include <iomanip>
using namespace std;
int main(void) {
int rows;
cout << "Enter the number of rows : ";
cin >> rows;
int i, j;
for(i = 0; i < rows; i++)
{
for(j = 0; j <= i; j++)
{
// find the closest side:
int distance = j; // distance to vertical side
if(i-j < distance)
distance = i-j; // distance to diagonal side
if((rows-1)-i < distance)
distance = (rows-1)-i; // distance to horizontal side
int r = rows - distance * 3;
// compute position on inner triangle:
int x = j - distance;
int y = i - distance * 2;
// compute start number for inner triangle:
int start = (((rows+1)*rows)/2) - (((r+1)*r)/2);
// output number based on side:
if(x==y) // diagonal side
cout << setw(2) << (start+y+1) << " ";
else if(y==(r-1)) // horizontal side
cout << setw(2) << (start+(r*2)-(x+1)) << " ";
else // vertical side
cout << setw(2) << (start+(r*3)-(y+2)) << " ";
}
cout << endl;
}
return 0;
}
以行等于7为例。在这种情况下,每个元素的distance
值将为:
(0)
0 0
0 (1) 0
0 1 1 0
0 1 (2) 1 0
0 1 1 1 1 0
0 0 0 0 0 0 0
具有相同距离值的所有元素形成三角形。外三角形的行数是7,下一个较小的行有4,然后是1.所以r = rows - (距离* 3)。
外三角形的左上角位于第0行第0列。第一个内部三角形是第2行,第1列,下一个是第4行第2列。所以给定行的位置/它所在的内三角上的列位置是通过从行中减去距离* 2和从列中减去距离得到的,因此y = i - (距离* 2)和x = j - 距离。
内三角形列存储在x中。内三角形行存储在y中。在上面的示例中,括号中的值是每个三角形的左上角,其中x = 0且y = 0.例如,对于距离= 1的三角形的左上角,i = 2且j = 1,所以x = 1 - 1 = 0,y = 2 - (1 * 2)= 0。
通过计算整个大三角形((行+ 1)*行)/ 2中的元素数量然后减去剩余元素数量(内部三角形中的元素数量)来找到起始值。
对于具有n行的三角形,元素总数为((n + 1)* n)/ 2,如下所示,对于行= 5:
1 X 0 0 0 0 0
2 X X 0 0 0 0
3 X X X 0 0 0
4 X X X X 0 0
5 X X X X X 0
1 2 3 4 5 6
要计算X的数量,我们可以看到它是(5 + 1)* 5矩形中元素数量的一半,因此是30的一半,即15。
如果在另一个内部有2个三角形,如下所示:
X
X X
X O X
X O O X
X X X X X
我们要计算X的数量,然后我们可以使用上面的公式计算整个三角形的大小得到15,然后计算内部三角形的大小,其中有2行为((2 + 1) )* 2)/ 2 = 3,并从较大的减去15-3 = 12.所以如果有12个X,那么第一个O必须是数字13.这就是我们如何计算输出的数量内三角的左上角。
一旦你计算了所有这一切,只需要弄清楚元素所在的内三角形的哪一面并将其打印出来。
答案 1 :(得分:2)
以下是关于如何使用递归解决此问题的一般概念。可能有一种方法可以节省空间的方式来解决这个问题,但我将其留给其他人。所以我们假设我们将它存储为x[i][j]
访问的数组数组,让我们说三角形边的大小是 n 。您可以谷歌了解如何动态创建数组数组。
现在我们想要的是三角形外部的等式。沿对角线的数字是(i(i + 1))/ 2,对于1&lt; = i &lt; = n 。对于1&lt; = i &lt; = n ,沿左边缘的数字是1+(i(i-1))/ 2。底部的数字是1+(n(n-1))/ 2 ..(n(n + 1))/ 2。
现在到了递归。设 j 是要编号的剩余三角形的大小, k 之前遇到的最高数字和( l , > m )三角形顶部的索引。使用上面的等式和前面的信息来计算数字并将其存储到剩余的三角形数组中。如果还有另一个内部,请使用最高数量和顶部索引进行递归。等等。
侧面尺寸的示例4.首先在外面编号。最高的先前数字是0.第一个位置的索引是(0,0)
1
9 2
8 x 3
7 6 5 4
我们还没有完成,因为我们仍然有一个尺寸为1的内部。所以当你递归时,三角形顶部的位置是(2,2),到目前为止最高的数字是9,剩下的三角形的大小是1。
现在尝试使用边长5.在第一个编号之后我们得到:
1
12 2
11 x 3
10 x x 4
9 8 7 6 5
剩余的三角形也从(2,2)开始,如第4侧所示。但是剩下的三角形的大小现在是2,到目前为止看到的最高数字是12。
完成所有递归后,打印出表格。
答案 2 :(得分:1)
简单的方法是使用数组。
#include <iostream>
using namespace std;
int main(){
int n;
cout <<"Enter the number of rows : ";
cin >> n;
int **tri = new int *[n];
for(int i=0; i<n; i++){
tri[i] = new int[i+1];
}
int v = 0, r = 0, c = 0;
for(int k = n-1; 0 <= k; k -=3){//k is total side size / 3, next k -2 -1
if(k==0){
tri[r][c] = ++v;
break;
}
for(int i = 0; i < k; ++i)//↘
tri[r++][c++] = ++v;
for(int i = 0; i < k; ++i)//←
tri[r][c--] = ++v;
for(int i = 0; i < k; ++i)//↑
tri[r--][c] = ++v;
r += 2; ++c;//next start position
}
//print
for(r = 0; r < n; ++r){
for(c = 0; c <= r; ++c)
cout << tri[r][c] << '\t';
cout << endl;
}
for(int i=0; i<n; i++){
delete[] tri[i];
}
delete[] tri;
}