C++ 用螺旋三角形粘住

C++ 用螺旋三角形粘住,c++,C++,我正在寻找一种算法,该算法可以对边为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<ios

我正在寻找一种算法,该算法可以对边为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();
    }
#包括
#包括
void main()
{
int n,i,j,v=0;
静态int k;
clrsc();
coutn;

对于(i=0;i,这里有一个关于如何使用递归来解决这个问题的一般想法。可能有一种方法可以以节省空间的方式来解决这个问题,但我将它留给其他人。因此,假设我们将其存储为
x[i][j]访问的数组
假设三角形边的大小为n。您可以在谷歌上搜索如何动态创建数组数组


现在我们要的是一个三角形外侧的方程,沿着对角线的数字是(i(i+1))/2 for 1这里有一个不使用任何数组存储的解决方案。螺旋可以被认为是一组相互之间的直角三角形。该函数迭代所有行和列,对于每个位置,它通过查找与外部三角形边缘最近的距离来计算元素所在的三角形,然后计算s其相对于该内三角形左上角的调整位置(x,y)、内三角形的行数(r)和内三角形的起始编号(起始+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,下一个较小的三角形的行数为4,然后为1。因此r=行-(距离*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

如果有两个三角形,一个在另一个内部,如下所示:

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。这就是我们如何计算内三角形左上角要输出的数字


一旦你计算了所有这些,你只需要计算出元素在内三角形的哪一边,然后打印出来。

简单的方法就是使用数组

#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;
}
#包括
使用名称空间std;
int main(){
int n;
cout n;
int**tri=新的int*[n];

对于(inti=0;iSo)你的问题是什么?为什么在这些非静态变量中有一个
静态的
变量?请注意
while(k==i)
if(k==i)相同
因为它只执行一次。很抱歉,我错放了if和whileYou在初始化它之前递增v。这没有意义。提示:从1到k的数字之和是k*(k+1)/2.你不需要循环。这很酷!它也有点复杂。不是不必要的复杂,但我发现逻辑很难理解。我想知道代码的程序证明会是什么样子。@rocky我会尝试充实一下解释代码是准确的,但我无法理解逻辑。重新阅读后代码和注释,我仍然对代码和巧妙的计算感到惊讶。但我理解这一点的方式是从简单的递归思想开始,然后通过在值中不断传播来找出如何进行计算。例如,距离是递归级别减去1。在递归情况下,数字赋值是基数d在顶部或第一个元素上,当然编号从“n选择2”开始三角形数字。一个轻微的代码建议。根据解释,
r=rows-distance*3
我认为比
r-=distance*3
更清晰。洛奇,谢谢,我已经根据你的建议更新了代码。我同意递归是理解这个问题的最简单方法,对你的答案进行了优化,获得了insight+1
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
X X
X O X
X O O X
X X X X X 
#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;
}