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

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

 /*===============================================================
本段代码是模拟往数组填数字的过程。
每填写一个值就判断该位置是否(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. 深入学习:Windows下Git入门教程(下)

    声明:由于本人对于Git的学习还处于摸索阶段,对有些概念的理解或许只是我断章取义,有曲解误导的地方还请见谅指正! 一.分支 1.1分支的概念. 对于的分支的理解,我们可以用模块化这个词来解释:在日常工 ...

  2. WinFrm窗体的传值方式

    比较简单的方法: 一:1.定义两个窗体 2.在父窗体中加入子窗体的属性 public ChildFrm ChildFrm { get; set; } 3.加载的时候: private void Par ...

  3. Cisco ASA 5505 Routing Between Two (Internal) VLANS

    Referenced:http://www.petenetlive.com/KB/Article/0000869 Problem I had to set this up for a client t ...

  4. Milk

    Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) ...

  5. 在Silverlight中实施RESTful调用

    在Silverlight中实施RESTful调用:   http://book.51cto.com/art/201006/206314.htm    http://bbs.csdn.net/topic ...

  6. sql2008+vs2008安装心得以及详细教程分享

    第一步,我把原来装的vs2005+sql2005全部卸载了 第二步,下载VS2008同时下载sql2008: 第三步,开始安装VS2008专业版,网上有很多给出了微软的地址,在这里我也贴一个吧 htt ...

  7. C语言字符串声明

    重新学习C语言字符串声明char *a="nihao";char a[]="nihao";什么区别?前者定义的是指针,并且指向字符串常量“nihao”,后者是字 ...

  8. 跟开涛老师学shiro -- INI配置

    之前章节我们已经接触过一些INI配置规则了,如果大家使用过如spring之类的IoC/DI容器的话,Shiro提供的INI配置也是非常类似的,即可以理解为是一个IoC/DI容器,但是区别在于它从一个根 ...

  9. NAT(未验证,后续见Linux服务器架构篇)

    通常小型企业或是学校单位大多数仅有一条对外的联机,然后全公司内的计算机全部通过这条联机连到因特网上,此时我们更需使用IP分享器来让这一条对外联机分享给所有公司内部员工使用,那么Linux能不能达到此一 ...

  10. 16年大连网络赛 1006 Football Games

    题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?cid=725&pid=1006 Football Games Time ...