由围绕矩形形状顺时针方向移动的数字组成的图案(长度和宽度每次减小)[关闭]

Posted

技术标签:

【中文标题】由围绕矩形形状顺时针方向移动的数字组成的图案(长度和宽度每次减小)[关闭]【英文标题】:Pattern consisting of numbers moving in clockwise direction around a rectangular shape (length and breadth decreasing each time) [closed] 【发布时间】:2011-08-12 15:10:48 【问题描述】:

我已经为许多模式编写了代码,但无法为此编写......甚至没有得到任何提示如何继续。

我想生成以下输出:

1  2  3  4  5 

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

...矩形的宽度和高度被指定为输入。

【问题讨论】:

【参考方案1】:

我会这样做:

将一个 5x5 二维整数数组初始化为 0。有一个 direction 变量,并为四个方向定义常量或 enum。从 (0, 0) 开始“向右”移动,用递增的值填充数组,直到碰到边缘或非 0 的数字。然后,递增方向(并换行)并继续。然后按行打印数组。

另一种使用循环的方法是遍历所有 (x, y) 坐标,并将 x 和 y 传递给一个函数,该函数为您提供该位置的值。我编写的函数与填充数组的函数完全相同,只是它不写入数组,当它到达给定的 (x, y) 时,它返回当前值。效率不是很高,但达到了效果。

【讨论】:

我们直到现在还没有教过数组,虽然我可以使用它..但是你只使用循环获得的任何其他逻辑 P.S.你可能想谷歌setw 以获得不错的输出。 +1 用于指导 OP 朝着正确的方向和替代方向发展。【参考方案2】:

由于这是一个家庭作业问题,我只想给你一个提示——从编写这个函数开始:

void predecessor(int in_x, int in_y, int& out_x, int& out_y);

我不会再说了——由你来弄清楚这个函数的用途:)

【讨论】:

【参考方案3】:

我会创建 4 个单独的循环。

循环 1 将创建 1 2 3 4 5 循环 2 将创建 6 7 8 9 循环 3 将创建 10 11 12 13 循环 4 将创建 14 15 16

完成此操作后,您已填充了正方形的外部,并在内部留下了一个较小的 3x3 正方形,可以以完全相同的方式填充,完全相同的 4 个循环。

【讨论】:

问题是如何直接打印这些数字而不使用数组? 谢谢,但是你将如何在屏幕上各自的位置显示它......我认为只有在我们知道坐标的情况下才有可能。 我的解决方案(我正在编写...)使用一个数组,然后打印完成的数组。我显然没有看到在计算结果时打印结果的算法。【参考方案4】:

我只是自己想出了这个,代码是逆时针的,但你可以通过改变方向数组来改变它。

int x = 0;
int y = 0;
int c = width * height;
int directions[4] =  0, 1, 0, -1;
int distances[2] =  height, width-1;
int di = 0;
int dx = directions[ di];
int dy = directions[ di+1];
int dis = distances[ di];

for( int i=0; i<c; i++)

    value = data[ y * width + x] = i;

    dis--;
    if( dis == 0)
    
        distances[ di % 2]--;
        di++;
        dx = directions[ di % 4];
        dy = directions[ (di+1) %4];
        dis = distances[ di % 2];
    
    x += dx;
    y += dy;

【讨论】:

【参考方案5】:
#include <stdio.h>
#include <stdlib.h>

#define SIZE 5

#define RIGHT 1
#define DOWN 2
#define LEFT 3
#define UP 4


void printArray1(int b[SIZE][SIZE], int size);
void printArray2(int b[SIZE][SIZE], int size);
int move(int b[SIZE][SIZE], int *xpos, int *ypos, int *movem, int number);


int main(void) 


    int i, j, num;
    int dir;
    int a[SIZE][SIZE] =  0 ; 

    printArray1(a, SIZE);
    printf("\n\n");
    printArray2(a, SIZE);

    dir = RIGHT;
    i = 0;
    j = 0;
    num = 1;
    for (; num <= (SIZE * SIZE); num++ )
        move(a, &i, &j, &dir, num);

    printArray1(a, SIZE);

    printf("\n\n");

    printArray2(a, SIZE);

    return 0;





void printArray1 (int b[SIZE][SIZE], int size)

    int i, j;
    for ( i = 0; i < size; i++ ) 
        for ( j = 0; j < size; j++ )
            printf("%3d  ", b[j][i]);
        printf("\n");
    
    printf("\n\n");
    return;


void printArray2 (int b[SIZE][SIZE], int size)

    int i, j;
    for ( i = 0; i < size; i++ ) 
        for ( j = 0; j < size; j++ )
            printf("%3d  ", b[i][j]);
        printf("\n");
    
    printf("\n\n");
    return;




int move(int b[SIZE][SIZE], int *xpos, int *ypos, int *movem, int number)


    int x, y, dirn, reqdDirn;

    x = *xpos;
    y = *ypos;
    dirn = *movem;

    if (b[x][y] == 0 ) 
        b[x][y] = number;
    


    reqdDirn = dirn;

    switch (dirn) 
    default:
        printf("Unexpected value");
        return;

    case RIGHT:
        x = x + 1;
        if (b[x][y] == 0) 
            if (x > SIZE-1) 
                reqdDirn = DOWN;
                x = SIZE - 1;
                y = y + 1;
                if (y > SIZE-1)
                    y = SIZE - 1;
            
         else 
            // just step back and change direction
            x = x - 1;
            y = y + 1;
            reqdDirn = DOWN;
        
        break;
    case DOWN:
        y = y + 1;
        if (b[x][y] == 0) 
            if (y > SIZE-1) 
                reqdDirn = LEFT;
                y = SIZE - 1;
                x = x - 1;
                if (x < 0)
                    x = 0;
            
         else 
            y = y - 1;
            x = x - 1;
            reqdDirn = LEFT;
        
        break;
    case LEFT:
        x = x - 1;
        if (b[x][y] == 0) 
            if (x < 0) 
                reqdDirn = UP;
                x = 0;
                y = y - 1;
                if (y < 0)
                    y = 0;
            
         else 
            // just step back and change direction
            x = x + 1;
            y = y - 1;
            reqdDirn = UP;
        
        break;
    case UP:
        y = y - 1;
        if (b[x][y] == 0) 
            if (y < 0) 
                reqdDirn = RIGHT;
                y = 0;
                x = x + 1;
                if (x > SIZE-1)
                    x = SIZE - 1;
            
         else 
            // just step back and change direction
            y = y + 1;
            x = x + 1;
            reqdDirn = RIGHT;
        
        break;

    


    *xpos = x;
    *ypos = y;
    *movem = reqdDirn;




 Output

  1    2    3    4    5  
 16   17   18   19    6  
 15   24   25   20    7  
 14   23   22   21    8  
 13   12   11   10    9  




  1   16   15   14   13  
  2   17   24   23   12  
  3   18   25   22   11  
  4   19   20   21   10  
  5    6    7    8    9  

【讨论】:

【参考方案6】:

//在java中 包ds1;

public class SpiralMatrix 

    public static void main(String[] args) throws Exception
          int[][] values = 1,2,3,4,5, 6,7,8,9,10, 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25;
            int x=0,y=0,z=0 ,length=values.length;
            System.out.println("Jai ShRaam \n array size :"+length+" \n \n");
        //Logic Starts
        for (int i=0;i<values.length;i++ )
        
            for (int j=0;j<values.length;j++ )
            

                if(i==j)
                            for(int k=i;k<length-i;k++)
                            
                                System.out.print(values[x][k]+" , ");
                            
                            x++;y++;

                            for(int k=x;k<length-i;k++)
                            
                                System.out.print(values[k][length-x]+" ; ");
                            
                            y++;
                            for(int k=i+length-y;k>=i;k--)
                            
                                System.out.print(values[length-x][k]+" - ");
                            
                            for(int k=i+length-y;k>=x;k--)
                            
                                System.out.print(values[k][i]+" : ");
                            

                //end of i==j
            //end of j loop
            //System.out.println();
        
        //Logic ends

    //end of psvm


//回答 1 , 2 , 3 , 4 , 5 , 10 ; 15; 20; 25; 24 - 23 - 22 - 21 - 16 : 11 : 6 : 7 , 8 , 9 , 14 ; 19; 18 - 17 - 12 : 13 ,

【讨论】:

【参考方案7】:
public ArrayList<Integer> spiralOrder(final List<ArrayList<Integer>> a) 
     ArrayList<Integer> result = new ArrayList<Integer>();
      int m = a.get(0).size();
      int n = a.size();
      if(m>1 && n>1)
         int loopCounter = (n > m)  ? m*2 : n *2 -1 ;
         int opr=1;
         int i=0,j=0;
         int opA=m,opB=n,opC=0,opD=1;
         for(int k=0;k < loopCounter ;k++)
              if(opr == 1)
                 int counter =0;
                 while(counter < opA)
                    System.out.print(a.get(i).get(j)+ ";");
                    result.add(a.get(i).get(j));
                    counter++;

                    if(j != opA-1)
                        j++;
                    
                    else
                        break;
                    
                 
                 opr =2;
                 continue;
             
             if(opr == 2)
                 i++;
                 int counter =1;
                 while(counter < opB)
                     System.out.print(a.get(i).get(j)+ ";");
                    result.add(a.get(i).get(j));
                    counter++;

                   if( i != opB-1)
                     i++;
                   
                   else
                       break;
                   
                 
                 opr =3;
                 continue;
             
             if(opr == 3)
                 j--;
                 int counter =j;
                 while(counter >= opC)
                     System.out.print(a.get(i).get(j)+ ";");
                    result.add(a.get(i).get(j));
                    counter --;
                     if(j != opC)
                     j--;
                    
                    else
                        break;
                    
                  
                 opr =4;
                 continue;
             
             if(opr == 4)
                 i--;
                 int counter = i;
                 while(counter >= opD)
                     System.out.print(a.get(i).get(j)+ ";");
                    result.add(a.get(i).get(j));
                    counter --;
                    if(i != opD)
                     i--;
                    else
                        break;
                    
                 
                 opr =1;
                 j++;
                 opA = opA -1;
                 opB = opB -1;
                 opC= opC +1;
                 opD = opD+1;
                 continue;
             
         

     

    else if(n ==1)
        for(int k=0;k < a.get(0).size();k++)
            result.add(a.get(0).get(k));
        
    

    // Populate result;
    return result;


【讨论】:

【参考方案8】:

这是我在 Java 中的解决方案:(我已经知道 Pointer 指向内存上的特定地址或被声明为在 C 上实现该目的,并且因为 Java 不支持我所做的指针使用非 C 指针逻辑)所以,也就是说,我使用指向矩阵“地址”(行、列)的逻辑来执行此操作。

static void MatrixTravelPointer(int [][] m)
    int pointerX = 0;
    int pointerY = 0;
    List<Integer> elements = new ArrayList<>();

    int maxlength_ = 0;
    int pos = 0;
    for(int i=0;i<m.length;i++)
        maxlength_ +=m[i].length;
    
    boolean turn = false;
    int turns = 1;

    while(pos<maxlength_)
    
        System.out.print(" "+m[pointerX][pointerY]);
        elements.add(m[pointerX][pointerY]);

        if( (pointerY == m[0].length - turns && pointerX == m.length - turns))
            turn = true;
            turns++;
        

        if(turns > 1 && turn == true && pointerX == turns - 1)
            turn = false;
        

        if(turn == false)
            if(pointerY < m[0].length - turns)
                pointerY++;
             else if(pointerX < m.length - turns)
                pointerX++;
            
        

        if(turn == true)
        
            if(pointerY >= turns - 1)
                pointerY--;
             else if(pointerX >= turns - 1)
                pointerX--;
            
        

        pos++;
    

    System.out.print("\n");
    Iterator it = elements.iterator();
    while(it.hasNext())
        System.out.print(" "+(int)it.next());
    
 

目前我的逻辑只适用于立方和矩形矩阵。 使用 4x4 矩阵的逻辑如下: 指针在矩阵中从 [0][0] 移动到 [0][3] ,此时它将移动指针从 [0][3] 变为 [3][3],想象一个自上而下的“ L" 在俄罗斯方块上,此时我们可以省略或删除顶行和右列,并使用 - 和从下到上从右到左反转旅行点。因为每次我们在“第二个转弯”上形成一个“L”时,我们都需要根据我们形成“L”的时间使用“turns”变量来减小行程大小(“L”大小)。

【讨论】:

问题是关于 C/C++,而不是 Java。【参考方案9】:
package arrays;

public class SpiralPrinting 

    public static void main(String[] args) 
        // TODO Auto-generated method stub
        int[][] a = new int[][]   1, 2, 3 ,  5, 6, 7 ,  9, 10, 11 ,
                 13, 14, 15  ;

        int cols = a[0].length;
        int rows = a.length;
        Business1 b = new Business1();
        b.print(a, rows, cols);
    


class Business1 

    int i = 0;
    int j = 0;
    int count = 0;

    public void print(int[][] a, int row, int col) 
        int max = row * col;
        while (count < max) 
            for (int k = 0; k < col; k++) 
                System.out.println(a[i][j]);
                j++;
                count++;
            
            row--;
            j--;
            i++;
            for (int k = 0; k < row; k++) 
                System.out.println(a[i][j]);
                i++;
                count++;
            
            i--;
            j--;
            col--;

            for (int k = 0; k < col; k++) 
                System.out.println(a[i][j]);
                j--;
                count++;
            
            row--;
            j++;
            i--;
            for (int k = 0; k < row; k++) 
                System.out.println(a[i][j]);
                i--;
                count++;
            
            i++;
            j++;
            col--;

        
    

【讨论】:

请始终提供解释。纯代码答案对未来的访问者几乎没有用处 问题是关于C/C++的,这个答案不是。

以上是关于由围绕矩形形状顺时针方向移动的数字组成的图案(长度和宽度每次减小)[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

雪花雪花雪花

顺时针打印矩阵

最小表示法,以及二维数组的比较方法

luogu P1205 方块转换

方块转换 transform

《算法竞赛进阶指南》 第二章 Acwing 137. 雪花雪花雪花 哈希