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

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

 /*===============================================================
本段代码是模拟往数组填数字的过程。
每填写一个值就判断该位置是否(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. php大力力 [017节]来来来,庆祝一下🎁大力力第一个数据库录入程序完成!

    庆祝一下

  2. 步步入佳境---UI入门(3) --单视图控制器

    视图控制器特点//1,抽象  视觉上没有效果//2,负责控制视图的显示方式//3,负责通知视图的显示内容//4,ios平台赋予的,收到内存警告和检测设备旋转@interface CHViewContr ...

  3. HDU 5009

    http://acm.hdu.edu.cn/showproblem.php?pid=5009 题意:一个数列,每个点代表一种颜色,每次选一个区间覆盖,覆盖的代价是区间内颜色种类数的平方,直到覆盖整个数 ...

  4. Ztree实现带checkBox的下拉框

    UI <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ArticleMove ...

  5. HDU 1004 Let the Balloon Rise(AC代码)

    #include <stdio.h> #include <string.h> ][]; ]={}; int main() { int n,i,j,k,max,loc; ){ m ...

  6. 【题解】【字符串】【Leetcode】Valid Palindrome

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...

  7. CoreOS 835.12.0 稳定版安装

    导读 CoreOS是一个基于Docker的轻量级容器化Linux发行版,为Docker而生,CoreOS作为Docker生态圈中的重要一员,日益得到各大云服务商的重视,发展风头正劲. CoreOS宣称 ...

  8. mysql 操作突然断网,MySQL: “lock wait timeout exceeded”

    show processlist;//显示所有进程select * from information_schema.innodb_trx;//查询锁的进程-- kill 310;//杀掉锁进程

  9. Java继承_接口练习题

    1.创建一个名称为StaticDemo的类,并声明一个静态变量和一个普通变量.对变量分别赋予10和5的初始值.在main()方法中输出变量值. 编写代码如下: package org.hanqi.pr ...

  10. POJ-2886 Who Gets the Most Candies?(线段树+模拟)

    题目大意:n个小孩按顺时针站成一圈,每次会有一个小孩出队(第一个出队的小孩已知),在他出队时会指定下一个出队的小孩,直到所有的小孩全部出队游戏结束.第p个出队的小孩会得到f(p)个糖果,f(p)为p的 ...