当前位置: 首页 > news >正文

平面设计比较好的网站网站建设验收书

平面设计比较好的网站,网站建设验收书,网站注册商标属于哪一类,品牌网络营销推广题目: [NOIP 2014 普及组] 螺旋矩阵 [信息与未来 2019] 粉刷矩形 题号: P2239 B3751 难度:普及一 两道题有一点类似,所以放到一个题解内。(都可以采用边界强行限制解题) 题目分析 初始化特定大小&…

题目:

[NOIP 2014 普及组] 螺旋矩阵

[信息与未来 2019] 粉刷矩形

题号:

P2239

B3751

难度:普及一

两道题有一点类似,所以放到一个题解内。(都可以采用边界强行限制解题)


题目分析

初始化特定大小(n*m)的网格,然后粉刷k步颜色,覆盖式粉刷,

每次粉刷指定初始位置和粉刷方向,知道遇到边界。

引入思路

先观察这道较为简单的粉刷矩形

逐步移动访问,以及制定边界阻挡。

关于该题,其实要做的步骤很简单,编写一个函数,然后遍历k次的访问参数调用给函数。

函数的功能,在指定的x,y位置,向指定的方向粉刷,遇到边界便终止本次。

1,关于边界,我们将数组扩大一圈,在这一圈铺上指定的阻挡值。

for(int i=0;i<=m;i++)
{    a[0][i]='1';a[n+1][i]='1';}
for(int i=0;i<=n;i++)
{a[i][0]='1';a[i][m+1]='1';}

2,内层按照题中指定要求,初始化为 ‘ . ’

for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)a[i][j]='.';

3,遍历调用绘图函数

for(int i=1;i<=k;i++) {
scanf("%d %d %c %c",&y,&x,&color,&direction);
getchar();
paint(a,y,x,color,direction);
}

3,核心步骤,编写绘画函数

我们先将传入的初始位置绘画指定颜色,然后沿着指定方向访问,继续绘画赋值,直到遇到边界为止。

void paint(char a[52][52],int x,int y,char color,char direction) {switch(direction) {//右 上 左 下
case 'R':     {a[x][y]=color;
while(a[x][++y]!='1')a[x][y]=color;}
break;
case 'U':     
{a[x][y]=color;
while(a[--x][y]!='1')a[x][y]=color;
}
break;
case 'L':     
{a[x][y]=color;
while(a[x][--y]!='1')a[x][y]=color;
}
break;
case 'D':     
{a[x][y]=color;
while(a[++x][y]!='1')a[x][y]=color;
}
break;}
}

到这里,粉刷矩形这道题便结束了。

核心思想:扩增一圈设定特定值的边界,逐步访问赋值。遍历调用。

到这里,我们接着进阶,看下一道,螺旋矩阵

首先,这道题在很多平台都出现过,属于比较经典的一道题,

例如 ACGO 平台上,作为一道入门题来使用,而洛谷上当做普及题。

同一类型的题造成难度差异的原因就在于是否限定了时间。

ACGO平台上的该题较为简单是因为它的时间范围放的很广,做题时只需要考虑数值正确就行。

来看代码

#include<stdio.h>int x=0;//初始位置,即将从左侧进入 一 行
int y=1;//初始位置,处在 一 行 (第二行)
int ctr = 1;//控制移动方向,初始化为1 向右
int num = 0;//控制螺旋数组的赋值。
int main()
{
int n;scanf("%d",&n);int a[n+2][n+2];for(int i=0;i<=n+1;i++){
a[i][0] = 1;
a[0][i] = 1;
a[n+1][i] = 1;
a[i][n+1] = 1;}//赋值边界
for(int q=1;q<=n;q++)
for(int p=1;p<=n;p++)    
a[q][p]=0;//赋值内界
while(1)
{if(ctr==1){if(a[y][x+1]==0)
{x++;num++;a[y][x]=num;}else{ctr=2;}}if(ctr==2){if(a[y+1][x]==0){y++;num++;a[y][x]=num;}else{ctr=3;}}if(ctr==3){if(a[y][x-1]==0){x--;num++;a[y][x]=num;}else{ctr=4;}}if(ctr==4){if(a[y-1][x]==0){y--;num++;a[y][x]=num;}else{ctr=1;}}
if(num==n*n)
break;}//whilefor(int py=1;py<=n;py++){
for(int px=1;px<=n;px++)
{printf("%d ",a[py][px]);
}if(py!=n)printf("\n");}  return 0;
}//main

该代码看着很长,但是逻辑也很简单,通过初始位置开始计算,然后初始向右开始移动访问赋值,直到遇到提前设定好的边界,然后转换指定方向( → ↓ ← ↑ )遇到边界或者已经赋值过的位置都会改变方向,如此便形成了一个螺旋的效果。

但是该带码稍微更改一下在洛谷平台该题是通过不了的,因为时间限制

洛谷平台上的 普及 螺旋矩阵

如果再用该代码,去强行通过,那么就会看到时间超时的警告

由于该算法逻辑比较简单,确实比较浪费时间,而且也没办法在该基础上优化,所以不得不更换算法。

我们尝试用数学规律来解析螺旋矩阵

首先是螺旋矩阵的构造规律

螺旋矩阵是按照顺时针螺旋顺序填充数字的,我们可以将一个 n x n 的螺旋矩阵看作是由多层嵌套的 “框” 组成。最外层是一个框,去掉最外层后,

里面又会形成一个新的 (n - 2) x (n - 2) 的螺旋矩阵,以此类推。

1. 第一行(i == 1

当元素位于第一行时,数字是从左到右依次递增填充的。例如,在一个 4 阶螺旋矩阵中,第一行的元素依次是 1, 2, 3, 4。所以,对于第一行的元素,

其值就等于它所在的列号 j,即 if(i == 1) return j;

2. 最后一列(j == n

在最后一列,数字是从上到下依次递增的。在第一行最后一列的元素是 n,之后每往下一行,元素值就增加 1。所以,对于最后一列的元素,

其值为 n + i - 1,即 if(j == n) return n + i - 1;

3. 最后一行(i == n

在最后一行,数字是从右到左依次递增的。在最后一列最后一行的元素是 2 * n - 1,之后每往左一列,元素值就增加 1。所以,对于最后一行的元素,

其值为 3 * n - j - 1,即 if(i == n) return 3 * n - j - 1;

4. 第一列(j == 1

在第一列,数字是从下到上依次递增的。在最后一行第一列的元素是 3 * n - 2,之后每往上一行,元素值就增加 1。所以,对于第一列的元素,

其值为 4 * n - i - 2,即 if(j == 1) return 4 * n - i - 2;

然后采用递归

当元素不在矩阵的边界上时,我们可以把矩阵缩小为去掉最外层后的子矩阵。去掉最外层后,新的矩阵阶数变为 n - 2,同时要查找的元素在新矩阵中的行号变为 i - 1,列号变为 j - 1

最外层元素的数量可以通过计算得到。最外层的四条边,每条边有 n 个元素,但四个角的元素会被重复计算一次,所以最外层元素的总数为 4 * n - 4,即 4 * (n - 1)

因此,对于不在边界上的元素,其值等于去掉最外层后的子矩阵中对应位置元素的值加上最外层元素的数量,即 return a(n - 2, i - 1, j - 1) + 4 * (n - 1);

举个例子,孩子们

以一个 4 阶螺旋矩阵为例:

1  2  3  4
12 13 14 5
11 16 15 6
10 9  8  7

假设我们要查找第二行第二列的元素(值为 13)。

  • 初始时,n = 4i = 2j = 2,元素不在边界上,进入递归调用。
  • 去掉最外层后,新的矩阵阶数 n' = 2,在新矩阵中,i' = 1j' = 1
  • 最外层元素的数量为 4 * (4 - 1) = 12
  • 对于新矩阵中第一行第一列的元素,根据边界情况,其值为 1。
  • 所以,原矩阵中第二行第二列的元素值为 1 + 12 = 13

通过这种递归的方式,我们可以根据元素在矩阵中的位置计算其在螺旋矩阵中的值

用数学算法优化过后,我们就得到了一个特别简便的代码

#include <stdio.h>
int x, y, z;
int a(int n, int i, int j) {if (i == 1)return j;if (j == n)return n + i - 1;if (i == n)return 3 * n - j - 1;if (j == 1)return 4 * n - i - 2;return a(n - 2, i - 1, j - 1) + 4 * (n - 1);
}
int main() {scanf("%d %d %d", &x, &y, &z);printf("%d", a(x, y, z));return 0;
}

这下就舒服多了。每每感叹数学对于编程算法的重要性。

当我问AI数学与编程的关系时,它只回了简短一句。

“数学凝自然秩序,编程赋其新生”

http://www.dtcms.com/a/592182.html

相关文章:

  • 做网站哪好上海网站建设费用
  • 网站建设策划书心得互联网行业有哪些
  • 网站做项目页面编辑wordpress
  • 乾安网站建设品牌营销和市场营销的区别
  • 制作京东网站建设好玩的微信小程序游戏排行榜前十名
  • 二级学院网站建设住建网官网
  • 写网站建设的论文wordpress显示加载进度
  • wordpress 修改dns打不开上海seo优化服务公司
  • 自适应h5网站模板wordpress 在线投稿
  • 网站如果不续费会怎样短视频seo代理
  • 交易网站制度建设做网站毕设任务书
  • 怎么免费建立自己网站温州网上商城网站建设
  • 精美网站宁波网站建设详细内容
  • 电影网站制作教程及步骤自适应网站如何做mip网页
  • 网站建设公司 枫子伽叩优化方案物理必修一电子版
  • 旅游网站建设的概念超链接到网站怎么做
  • 公司做网站都咨询哪些问题网站首页设计多少钱
  • 南京网站网站建设app怎么制作多少钱
  • 网站死链存在的问题网页小游戏flash不能正常运行
  • 用 htmi5做网站保定 网站制作
  • 个人网站需要备案网站开发语言什么意思
  • 外贸网站域名赏析免费推广企业网站
  • 小型企业的网站建设论文网站备案 营业执照
  • 选择做网站销售的优势网站的优化方案怎么写
  • 徐汇制作网站哪家好一流的营销型网站建设
  • 企业的网站建设青岛企业建站
  • 桃浦做网站wordpress缓存无法清除缓存
  • 开发网站的成本只用wordpress 主题
  • 哪些做任务可以赚钱的网站摄影网站首页设计
  • 深圳婚庆网站建设关键词爱站网关键词挖掘工具