5 条题解

  • 4
    @ 2023-11-15 17:04:18

    介绍一种递归写法

    #include<stdio.h>
    
    int n, cnt;
    int a[105][105], vis[105][105];
    
    int check(int x, int y)
    {
    	if(x < 1 || x > n || y < 1 || y > n) return 0;//看是否越界(出地图) 
    	else if(vis[x][y]) return 0; //判断是否走过 
    	else return 1; //能走 
    }
    
    void dfs(int x, int y, int dirt)
    {
    	a[x][y] = ++cnt;
    	vis[x][y] = 1;//标记这个点是否走过 
    	
    	while(1) //因为要四个方向轮流转,所以是一个周期。 
    	{
    		if(cnt == n * n) return ; //当填满n * n结束 
    			
    		if(dirt % 4 == 0) //第一次往下 
    		{
    			if(check(x + 1, y)) dfs(x + 1, y, dirt);
    			else dirt++; //直到下边没地方走 
    		}
    		
    		if(dirt % 4 == 1) 
    		{
    			if(check(x, y - 1)) dfs(x, y - 1, dirt);//第二次往左 
    			else dirt++;
    		}
    		
    		if(dirt % 4 == 2) //第三次往上 
    		{
    			if(check(x - 1, y)) dfs(x - 1, y, dirt);
    			else dirt++;
    		}
    		
    		if(dirt % 4 == 3) //第四次往右 
    		{
    			if(check(x, y + 1)) dfs(x, y + 1, dirt);
    			else dirt++;
    		}
    	}
    	
    }
    
    int main()
    {
    	scanf("%d",&n);
    	dfs(1, n, 0);//由题目看出起点在(1, n),第三个量存的是方向 
    	
    	for(int i = 1; i <= n; i++)
    	{
    		for(int j = 1; j <= n; j++)
    		{
    			printf("%d ",a[i][j]);
    		}
    		printf("\n");
    	}
    	
    	return 0;
    }
    
    • 4
      @ 2023-10-15 23:51:34
      #include<stdio.h>
      int main()
      {
      	int n;
      	scanf("%d",&n);
      	int nn=n*n;
      	int x=1,y=n;
      	int fx=0;
      	int num[101][101]={0};
      	for(int i=1;i<=nn;i++){
      		num[x][y]=i;
      		if(fx==0){               //下
      			if(x+1>n||num[x+1][y]!=0){ //提前预判下一位越界或者碰头  
      				fx=1;//改变方向
      				y--;
      			}
      			else{
      				x++;
      			}
      		}
      		else if(fx==1){          //左
      			if(y-1<1||num[x][y-1]!=0){
      				fx=2;//改变方向
      				x--;
      			}
      			else{
      				y--;
      			}
      		}
      		else if(fx==2){          //上
      			if(x-1<1||num[x-1][y]!=0){
      				fx=3;//改变方向
      				y++;
      			}
      			else{
      				x--;
      			}
      		}
      		else if(fx==3){          //右
      			if(num[x][y+1]!=0){
      				fx=0;//改变方向
      				x++;
      			}
      			else{
      				y++;
      			}
      		}
      	}
      	for(int i=1;i<=n;i++){
        		for(int j=1;j<=n;j++){
      			printf("%d ",num[i][j]);
      		}
      		printf("\n");
      	}
      	return 0;
      }
      
      • @ 2023-11-14 20:45:25

        再补充一点奥,if里判断碰头和越界后,y和x还要变一次的原因是还需要同时判断下一次的坐标值,所以说要提前判断

      • @ 2025-1-22 19:04:10

        这个思路最简便👍 👍 👍 👍

      • @ 2025-11-2 11:48:14

        这个思路好

      • @ 2025-11-12 19:48:59

        太牛了

    • 1
      @ 2023-8-27 13:09:32
      wasd = [[0, 1], [-1, 0], [0, -1], [1, 0]]#控制snake方向
      n = int(input())
      square = [[0 for _ in range(n + 1)] for __ in range(n + 1)]#创建初始矩阵,多创建一格防止outofindex
      
      def sq_print():
          #按题目格式打印最终结果
          for i in range(n):
              for j in range(n):
                  print(square[i][j], end = ' ')
              print()
      
      def sq_fill():
          x = n - 1
          y = 0#初始位置
          ctrl = 0#控制转向符
          for i in range(1, n * n + 1):
              square[y][x] = i
              x += wasd[ctrl][0]
              y += wasd[ctrl][1]
              if ((x == n - 1) and (y == n - 1)) or ((x == 0) and (y == n - 1)) or ((x == 0) and (y == 0)) or (square[y + wasd[ctrl][1]][x + wasd[ctrl][0]] != 0):
                  #当snake触及矩阵底部,或snake将要前往的下一个位置已经有数字的时候,控制转向
                  ctrl += 1
                  ctrl %= 4#控制符应该是{0,1,2,3},即模4的循环群
      
      sq_fill()
      sq_print()
      
      • 0
        @ 2025-11-18 21:23:40
        #include<stdio.h>
        int main()
        {
            int n;
            int a[100][100]={0};
            scanf("%d",&n);
            if(n==1)
            {
                printf("1");
                return 0;
            }
            if(n%2!=0)//奇数比偶数多一个最中间的值
            {
                a[n/2][n/2]=n*n;
            }
            int j=0;
            for(int i=0;i<n/2;i++)//控制次数 一层就是一次循环
            {//注意:每层小循环的区间 左闭右开
                for(int k=0;k<n-1-2*i;k++)//上到下
                {
                    a[i+k][n-1-i]=++j;
                }
                for(int k=0;k<n-1-2*i;k++)//右到左
                {
                    a[n-1-i][n-1-k-i]=++j;
                }
                for(int k=0;k<n-1-2*i;k++)//下到上
                {
                    a[n-1-k-i][i]=++j;
                }
                for(int k=0;k<n-1-2*i;k++)//左到右
                {
                    a[i][i+k]=++j;
                }
            }
            for(int i=0;i<n;i++)
            {
                for(int k=0;k<n;k++)
                {
                    printf("%d ",a[i][k]);
                }
                printf("\n");
            }
            return 0;
        }
        
        • 0
          @ 2025-11-2 11:47:44
          #include <stdio.h>
          int main() {
              int n;
              scanf("%d", &n);  
              int matrix[100][100] = {0};
              int i = 0, j = n - 1;  //表示的是起始位置:右上角 (0, n-1)
              int num = 1;  // 要填充的数值,从 1 开始
              int dir = 0;  // 方向状态:0-下,1-左,2-上,3-右
          
              // 填充 1 ~ n² 到矩阵
              while (num <= n * n) {
                  matrix[i][j] = num++;  // 填充当前位置
                  // 根据当前方向,移动到下一个位置或切换方向
                  switch (dir) {
                      case 0:  // 方向:向下
                          if (i + 1 < n && !matrix[i + 1][j]) {
                              i++;  // 可向下移动,继续向下
                          } else {
                              dir = 1;  // 无法向下,切换为“向左”
                              j--;
                          }
                          break;
                      case 1:  // 方向:向左
                          if (j - 1 >= 0 && !matrix[i][j - 1]) {
                              j--;  // 可向左移动,继续向左
                          } else {
                              dir = 2;  // 无法向左,切换为“向上”
                              i--;
                          }
                          break;
                      case 2:  // 方向:向上
                          if (i - 1 >= 0 && !matrix[i - 1][j]) {
                              i--;  // 可向上移动,继续向上
                          } else {
                              dir = 3;  // 无法向上,切换为“向右”
                              j++;
                          }
                          break;
                      case 3:  // 方向:向右
                          if (j + 1 < n && !matrix[i][j + 1]) {
                              j++;  // 可向右移动,继续向右
                          } else {
                              dir = 0;  // 无法向右,切换为“向下”
                              i++;
                          }
                          break;
                  }
              }
              for (int row = 0; row < n; row++) {
                  for (int col = 0; col < n; col++) {
                      printf("%d ", matrix[row][col]);//col是列,翻译软件说的column
                  }
                  printf("\n");  
              }
              return 0;
          }
          
          • 1

          信息

          ID
          131
          时间
          3000ms
          内存
          128MiB
          难度
          6
          标签
          (无)
          递交数
          638
          已通过
          211
          上传者