编程能力提高------蛇形填数(方块填数+三角形填数)

2024-01-24 23:58

本文主要是介绍编程能力提高------蛇形填数(方块填数+三角形填数),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

回忆曾经:

考研复试上机做题时,遇到过一次这个蛇形填数问题,当时不会做;后来又遇到一个蛇形填充(基于三角形),也不会做;这让我下定决心,一定要找到这两个问题的解。后来才知道,这种问题,是学习ACM的入门问题。

蛇形填数(一)蛇形矩阵


问题一:描述 

以下内容参考《算法竞赛入门经典(第2版)刘汝佳》

在n*n方阵里填入1,2,„,n*n,要求填成蛇形。例如n=4时方阵为 

10    11   12   1 

  9    16   13   2 

  8    15   14   3

  7     6     5    4  

上面的方阵中,多余的空格只是为了便于观察规律,不必严格输出。n≤8。

问题分析:

      字符的特殊图形输出问题,我们暂时可以分为2类。
      第一类是有一定对称性的几何图形,比如说打印倒三角形或者菱形等。这种题目一般思路就是找出图形的特点(对称性等)与循环变量(行号,列号)之间的关系。我们可以假设行用i表示,列用j表示。我们的目的就是找出i,j与图形之间的对应关系。按图形形状的不同,i和j之间的复杂性不同。但是都可以看做是在寻找一种或多种"静态关系"。 
       第二类是有一定规律性的图形,比如蛇形填数,走棋盘等。这种题目的一般思路就是找出题目中对图形的限制条件(不能出界,按照一定规则填充等)。我们首先要通过观察理解用到的“规则”,然后用各种循环和if语句将这些"规则"变成程序语句。同样,根据"规则"不同,复杂性也不同。但是都可以看做是在寻找一种或多种i和j之间的"动态关系"。 
      通过观察,我们可以看出规则:在规定的方阵n*n里,在不越界及不走重复位置的前提下,填充元素遵循右下左上的规定.即向右走到顶后向下走到顶,再向左走到顶,向上走到顶。

      类比数学中的矩阵,可以用一个二维数组来存储题目中的方阵。只要声明一个“int  a[maxn][maxn]”,就可以获得一个大小为maxn*maxn的方阵,在声明时,二维的大小不必相同,因此也可以声明int a[30][50]这样的数组。

      从1开始依次填写。设“笔”的坐标为(x,y),则一开始x=0,y=n-1,即第0行,第n-1列。“笔”的移动轨迹是:下,下,下,左,左,左,上,上,上,右,右,下,下,左,上。总之,先是下,到不能填为止,然后是左,接着是上,最后是右。“不能填”是指再走就出界(例如4→5),或者再走就要走到以前填过的格子(例如12→13)。如果把所有格子初始化为0,就能很方便地加以判断。在这里我们就要提到在很多时候都要用到的判断方法"预判".即提前一格判断下一格是否越界,如果下一格越界就不再移动。

#include <stdio.h>
#include <string.h>
#define MAXN 20
int a[MAXN][MAXN];//数组空间分配在main内外,有点区别int main()
{int n, x, y, count = 1;scanf("%d", &n);memset(a, 0, sizeof(a));//用于判断格子是否被填数,memset可以初始化二维数组。x = 0; y = n-1;a[x][y] = 1;while(count < n*n){while(x+1<n && !a[x+1][y]) a[++x][y] = ++count; //先判断越界,再判断格子是否填过数 while(y-1>=0  && !a[x][y-1]) a[x][--y] = ++count;while(x-1>=0  && !a[x-1][y]) a[--x][y] = ++count;while(y+1<n && !a[x][y+1]) a[x][++y] = ++count;     }for(x = 0; x < n; x++){for(y = 0; y < n; y++)printf("%3d", a[x][y]);printf("\n");}system("PAUSE");	return 0;
}

        4条while语句有些难懂,其实是有原则的。先判断,再行走,而不是走一步后发现越界再退回来。这样则需要进行“预判”,即是否越界,以及如果继续往下走会不会到达一个已经填过的格子。越界只需判断x+1<n,因为y的值并没有修改;下一个格子是(x+1,y),因此需要判断a[x+1][y]==0,简写成 “!a[x+1][y] ”。

       实现方式有多种。如果在编程时,先移动位置再判断是否合适。如果发现越界再退回来一步,无需提前进行预判是否越界或是否已填过。实现方式,见下面。

#include <stdio.h>
#include <string.h>
#define MAXN 20
int arr[MAXN][MAXN];//数组空间分配在main内外,有点区别int main() {int n, i, j, count = 1;printf("请输入方阵的宽带n:");scanf("%d", &n);memset(arr, 0, sizeof(arr));//用于判断格子是否被填数,memset可以初始化二维数组。i = 0;      //行标j = n-1;    //列标while(count <= n*n) {while(arr[i][j] == 0 && i < n)arr[i++][j] = count ++;i --;                           //回退一格j --;while(arr[i][j] == 0 && j >= 0)arr[i][j --] = count ++;j ++;                           //回退一格i --;while(arr[i][j] == 0 && i >= 0)arr[i --][j] = count ++;i ++;                           //回退一格j ++;while(arr[i][j] == 0 && j < n)arr[i][j ++] = count ++;j --;                           //回退一格i ++;}printf("输出方阵为:\n");for(i = 0; i < n; i++) {for(j = 0; j < n; j++)printf("%3d", arr[i][j]);printf("\n");}system("PAUSE");return 0;
}


蛇形填数(二)蛇形三角


问题二:描述 

1    2   3  4  5
12  13  14  6
11  15  7
10  8
9
跟蛇形填数一样,只是填数要求按照三角形填。

输入
第一行有一个N,表示N组测试数据
接下来每组数据包括一个数字X,表示三角形的边长,0< X <1000
输出
输出填好之后的图
样例输入
2
5
4
样例输出
1  2  3  4  5
12 13 14 6
11 15 7
10 8
91  2  3  4
9  10 5
8  6
7
#include <iostream>
#include <string.h>
using namespace std;
const int MAXN = 100;
int data[MAXN][MAXN];
int main() {
int n,length;
cin>>n;
while(n--) {
memset(data,0,sizeof(data));
cin>>length;
int x=0,y=0,cnt=1;
data[x][y]=cnt;
while(cnt<((length+1)*length)/2) {
while ((y+1<length-x) && !data[x][y+1])
data[x][++y]=++cnt;
while ((x+1<length) && (y-1)>-1 &&!data[1+x][y-1] )
data[++x][--y]=++cnt;
while (x-1>-1 && (!data[x-1][y]))
data[--x][y]=++cnt;
}
for (int i=0; i< length ; i++) {
for (int j=0; j<length-i; ++j) {
cout<<data[i][j]<<"  ";
}
cout<<endl;
}
cout<<endl;
}
return 0;
}





这篇关于编程能力提高------蛇形填数(方块填数+三角形填数)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/641453

相关文章

如何提高Redis服务器的最大打开文件数限制

《如何提高Redis服务器的最大打开文件数限制》文章讨论了如何提高Redis服务器的最大打开文件数限制,以支持高并发服务,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录如何提高Redis服务器的最大打开文件数限制问题诊断解决步骤1. 修改系统级别的限制2. 为Redis进程特别设置限制

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【WebGPU Unleashed】1.1 绘制三角形

一部2024新的WebGPU教程,作者Shi Yan。内容很好,翻译过来与大家共享,内容上会有改动,加上自己的理解。更多精彩内容尽在 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信号:digital_twin123 在 3D 渲染领域,三角形是最基本的绘制元素。在这里,我们将学习如何绘制单个三角形。接下来我们将制作一个简单的着色器来定义三角形内的像素

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

键盘快捷键:提高工作效率与电脑操作的利器

键盘快捷键:提高工作效率与电脑操作的利器 在数字化时代,键盘快捷键成为了提高工作效率和优化电脑操作的重要工具。无论是日常办公、图像编辑、编程开发,还是游戏娱乐,掌握键盘快捷键都能带来极大的便利。本文将详细介绍键盘快捷键的概念、重要性、以及在不同应用场景中的具体应用。 什么是键盘快捷键? 键盘快捷键,也称为热键或快捷键,是指通过按下键盘上的一组键来完成特定命令或操作的方式。这些快捷键通常涉及同

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏