本题可以直接模拟填数字,也可以直接计算结果。

代码一:(这个代码,缺陷在于数组太大,浪费内存啊。另外,循环次数也不少。总之,时间空间的消耗都不小。)

 /*===============================================================
本段代码是模拟往数组填数字的过程。
每填写一个值就判断该位置是否(i,j)。若寻到目标位置,
则输出答案。
=================================================================*/
#include<stdio.h>
int a[][]={};//这个大小的静态数组尚可申请,但假如是放在函数内部声明却不行了的。这个大小大概是9MB,但距离30000*30000的大小实在是太远了。
int main()
{
int n,i,j;
int m;//m表示总共的层数
int k,p,q;//循环变量
int flag=;//标志性变量:等于0表示尚未循环到目标元素(i,j)
int t;
int len; scanf("%d%d%d",&n,&i,&j);
m=(n+)/; //m表示总共的层数
t=; //t表示要填进数组的数字
for(k=;k<=m&&flag==;k++)
{
p=k,q=k; //(k,k)是第k层左上角坐标点
len=n-*(k-);//表示当前层中每一条边的元素个数
for(;q<=(k+len-);q++)//填充当前层的顶边
{
a[p][q]=t;
if(p==i&&q==j)
{
printf("%d\n",a[p][q]);
return ;
}
t++;
}
q--;
p++;
for(;p<=(k+len-);p++)//填充当前层的右边
{
a[p][q]=t;
if(p==i&&q==j)
{
printf("%d\n",a[p][q]);
return ;
}
t++;
}
p--;
q--;
for(;q>=k;q--)//填充当前层的下边
{
a[p][q]=t;
if(p==i&&q==j)
{
printf("%d\n",a[p][q]);
return ;
}
t++;
}
q++;
p--;
for(;p>k;p--)//填充当前层的左边
{
a[p][q]=t;
if(p==i&&q==j)
{
printf("%d\n",a[p][q]);
return ;
}
t++;
}
}
return ;
}

代码二:(这个代码缺陷在于循环时间没减少……)

 /*===============================================================
本段代码也是模拟往数组填数字的过程。但没有申请数组内存来存储数据。
而是只用一个变量表示每一次要填写的数字。
毕竟题目只要输出(i,j)位置的值,故不用保存整个数组。
只需要判断每一次模拟到的位置是否是(i,j)即可。
=================================================================*/
#include<stdio.h>
int main()
{
int n,i,j;
int m;//m表示总共的层数
int k,p,q;//循环变量
int flag=;//标志性变量:等于0表示尚未循环到目标元素(i,j)
int t;
int len; scanf("%d%d%d",&n,&i,&j);
m=(n+)/; //m表示总共的层数
t=; //t表示要填进数组的数字
for(k=;k<=m&&flag==;k++)
{
p=k,q=k; //(k,k)是第k层左上角坐标点
len=n-*(k-);//表示当前层中每一条边的元素个数
for(;q<=(k+len-);q++)//填充当前层的顶边
{
if(p==i&&q==j)
{
printf("%d\n",t);
return ;
}
t++;
}
q--;
p++;
for(;p<=(k+len-);p++)//填充当前层的右边
{
if(p==i&&q==j)
{
printf("%d\n",t);
return ;
}
t++;
}
p--;
q--;
for(;q>=k;q--)//填充当前层的下边
{
if(p==i&&q==j)
{
printf("%d\n",t);
return ;
}
t++;
}
q++;
p--;
for(;p>k;p--)//填充当前层的左边
{
if(p==i&&q==j)
{
printf("%d\n",t);
return ;
}
t++;
}
}
return ;
}

代码三:(这个代码应该算是比较完美了,时间空间都降下来了,而且是O(1)时间的算法。)

 /*===============================================================
本段代码不是模拟填写数字的过程,而是直接根据i和j的值计算(i,j)所在的层k。
然后计算第k层左上角(k,k)位置处的元素值。
接下来呢,要寻到 (i,j)处的值,可以有两种方法:
(1)模拟填数字的过程环绕一圈寻找(i,j)。
(2)根据i,j的值依次计算(k,k)距离(i,j)的几个段的距离即可得到答案。
这里使用第二个方案。
=================================================================*/
#include<stdio.h>
int main()
{
int n,i,j;
int k,t;
freopen("matrix10.in","r",stdin);
freopen("matrix10.txt","w",stdout);
scanf("%d%d%d",&n,&i,&j);
//根据i判断(i,j)所在层数k
t=(n+)/;
if(i<=t)
{
if(j<=t) k=(i<=j?i:j);//(i,j)在左上部分
else k=(i<(n+-j)?i:(n+-j)); //(i,j)在右上部分
}
else
{
if(j<=t) k=(n+-i)<j?(n+-i):j; //(i,j)在左下部分
else k=(n+-i)<(n+-j)?(n+-i):(n+-j); //(i,j)在右下部分
}
//计算第k层左上角坐标为(k,k)的数t
k--;
t=n*n-(n-*k)*(n-*k)+;//注意:n-2k表示剥去k层之后剩余部分的行数和列数.(i,j)所在层没被剥掉,故而要先执行k--。
k++;
if(i==k) //(i,j)在第k环的上边线
t=t+(j-k);
else if(j==k+n-*(k-)-) //(i,j)在环的右边.
t=t+(n-*(k-)-)+(i-k);
else if(i==k+n-*(k-)-)//(i,j)在环的下边
t=t+(n-*(k-)-)+(n-*(k-)-)+((k+n-*(k-)-)-j);
else t=t+(n-*(k-)-)+(n-*(k-)-)+(n-*(k-)-)+((k+n-*(k-)-)-i);
printf("%d\n",t);
return ;
}

关于计算层数的代码:

其实是把整个数组分为左上、右上、左下和右下四个区域分别处理。

 #include<stdio.h>
int main()
{
int n,i,j,k,t;
scanf("%d",&n);
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
{
t=(n+)/;
if(i<=t)
{
if(j<=t) k=(i<=j?i:j);//(i,j)在左上部分
else k=(i<(n+-j)?i:(n+-j)); //(i,j)在右上部分
}
else
{
if(j<=t) k=(n+-i)<j?(n+-i):j; //(i,j)在左下部分
else k=(n+-i)<(n+-j)?(n+-i):(n+-j); //(i,j)在右下部分
}
printf("%d ",k);
}
printf("\n");
}
return ;
}

关于计算(i,i)处的值:

n*n-(n-2*k)*(n-2*k)+1

其中,n*n是数字总的个数,k是表示被剥去的层数(注意:假如(i,j)在第k层,则被剥去的是(k-1)层。)

(n-2*k)*(n-2*k)表示剥去之后,剩余部分的元素的个数。

如何理解n-2*k呢?其实啊,就是“每剥去一层,行和列的数量都会减少2,于是总共减少的数量就是2*k。剩余的部分自然就是n-2*k了。”

螺旋矩阵 noip2014普及组的更多相关文章

  1. noip201403螺旋矩阵【普及组】数学算法

    思路如下: 1.输入n>>a>>b; 2.用一个循环缩小范围求出a,b所示的数所在的圈数q; 3.再一个循环求出圈数q的第1个数的值sum; 4.用四个if判断a,b所示的数在 ...

  2. 【NOIP2014 普及组】螺旋矩阵

    [NOIP2014 普及组]螺旋矩阵 一.题目 [NOIP2014 普及组]螺旋矩阵 时间限制: 1 Sec  内存限制: 128 MB 提交: 18  解决: 0 [提交][状态][讨论版] 题目描 ...

  3. [NOIP2014] 普及组

    珠心算测验 模拟. 将所有“两个不同数之和”装进桶里,扫描原数组记录满足条件的数的个数. /*by SilverN*/ #include<iostream> #include<alg ...

  4. noip2014普及组——珠心算测验

    题目描述 珠心算是一种通过在脑中模拟算盘变化来完成快速运算的一种计算技术.珠心算训练,既能够开发智力,又能够为日常生活带来很多便利,因而在很多学校得到普及.    某学校的珠心算老师采用一种快速考察珠 ...

  5. [NOIP2014普及组]子矩阵

    题目:洛谷P2258.Vijos P1914.codevs 3904. 题目大意:给你一个矩阵,要你找一个r行c列的子矩阵,求最小分值(子矩阵和分值的定义见原题). 解题思路:n和m比较小,考虑暴力. ...

  6. noip2014普及组 比例简化

    题目描述 在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果.例如,对某一观点表示支持的有1498 人,反对的有 902人,那么赞同与反对的比例可以简单的记为1498:902. 不过,如 ...

  7. [NOIP2014普及组T1]珠心算测验 - NTT

    求数组有多少个数,恰好等于集合中另外两个(不同的)数之和? 注意到数集比较小,而且涉及到下标的加法,可以很自然地想到卷积 注意减去自己加自己的贡献 真是一道NTT练手好题 #include <i ...

  8. SYCOJ246螺旋矩阵

    题目-螺旋矩阵 (shiyancang.cn) noip201403螺旋矩阵[普及组]数学算法 - 大本营 - 博客园 (cnblogs.com) 以下为搬运代码.一个为算圈数,另外一个是数学方法 思 ...

  9. NOIP 2014 普及组 T3 螺旋矩阵

    [题意] 已知:n,r,c(n<=30000) 条件:给定n行n列的螺旋矩阵(从矩阵的左上角(1,1)出发,初始时向右移动:如果前方是未曾经过的格子, 则继续前进,否则右转:重复上述操作直至经过 ...

随机推荐

  1. Python入门(四,高级)

    一,面向对象 面向对象技术简介 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的. ...

  2. [转]Why Not Paxos

    http://blog.csdn.net/cszhouwei/article/details/38374603 Why Not Paxos Paxos算法是莱斯利·兰伯特(LeslieLamport, ...

  3. Autoresizing和AutoLayout

    1 使用Autoresizing的方式进行界面布局 1.1 问题 Autoresizing是IOS旧版的自动布局技术,现在仍然被很多企业使用.本案例将学习如何使用Autoresizing完成界面的布局 ...

  4. C++学习笔记15:操作符重载的函数原型列表(推荐)

    //普通四则运算 friend A operator +(const A & lhs, const A & rhs); friend A operator -(const A & ...

  5. spark streaming 实现接收网络传输数据进行WordCount功能

    package iie.udps.example.operator.spark; import scala.Tuple2; import org.apache.spark.SparkConf; imp ...

  6. 使用使用for in 语句,并对数组中元素进行了增删操作,报错却不知怎么办?

    解决方案: 在forin遍历过程中不要对遍历数据进行修改, for in 的时候如果在操作内移除会打乱 他的count 导致出错,如果要修改尽量用for循环

  7. 215. Kth Largest Element in an Array

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  8. ZOJ 1205 Martian Addition

    原题链接 题目大意:大数,20进制的加法计算. 解法:convert函数把字符串转换成数组,add函数把两个大数相加. 参考代码: #include<stdio.h> #include&l ...

  9. 使用move_base导航 ---13

    摘要: 原创博客:转载请表明出处:http://www.cnblogs.com/zxouxuewei/ 我们现在准备用move_base简单的移动机器人记住,一个“pose”在ros的意思是一个位置和 ...

  10. UVa 1394 约瑟夫问题的变形

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...