题目描述
第一行:1个奇数N。
第二行:1个整数A。 (0 < A <= N*N)
一个整数,表示编号A地砖的位置编码。
20
28
数据范围:
80%数据 0 < N < 1000;
100%数据 0 < N < 100000.
数据量决定算法,先看数据量。80%数据0<N<1000;
100%数据0<N<100000;
这题看题目时,想必很多同学都想到能用二维数组打表,然后再做吧,这样固然轻松,但一看数据量,集体懵比了。数组会爆掉的。
只能刷八十分。
所以,我们只能找规律了。
而这题的规律也很好找,稍微画画图就想到了。
我是第一次写博客画图,画的不好请多多包涵。
画出上图之后,规律显而易见。我在此总结了三个规律:
第一个规律是用来确定整数A是在第几层的,这是得出第三个规律的前提,不难发现每一层的最大数都是由上一层的最大数加上(这一层层数减1乘8的积)的。
第二个规律,这是用来得出第一个规律的前提,1的横坐标是n÷2+1,纵坐标也是如此。
第三个规律,得出每一层的第一个数,这也是最关键的一步,为了之后绕一圈求答案做铺垫。如图所示,每层的第一个数即是那一层最大的数(也就是最后一个数)-(这一层层数减1乘8的积)再加上1;
有了这三个规律,我们就会发现,做这题变得简单多了,我们就可以完整地做出整道题(也就是正解了)。
做法如下:
1:首先依规律求出三个条件;
2:接着开始从这一层的第一个数开始绕一圈,寻找这个数,最后找到这个熟后输出就行了。
程序如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
long long n,a,b,c,d,m,s=1,e,f,g=1;
int main()
{
freopen("1022.in","r",stdin);
freopen("1022.out","w",stdout);
cin>>n>>m;
a=n/2+1;//求一的坐标
b=n/2+1;//求一的坐标
if(m==1)
{
cout<<a*n+b;
return 0;
}
long long i=1;
while(s<m)//算出整数A所在的层
{
c=c+8;
s=s+c;
i++;
}
d=i;
c=s-c+1;//整数A在的层的第一个数
e=a-d+1;//整数A在的层的第一个数的坐标
f=b-d+1;//整数A在的层的第一个数的坐标
g=d+d-2;//每次前进需要加的值
c=c+g;
// 绕一圈
if(c>=m)
{
f=f+(g-(c-m));
cout<<e*n+f;
return 0;
}
else
f=f+g;
c=c+g;
if(c>=m)
{
e=e+(g-(c-m));
cout<<e*n+f;
return 0;
}
else
e=e+g;
c=c+g;
if(c>=m)
{
f=f-(g-(c-m));
cout<<e*n+f;
return 0;
}
else
f=f-g;
c=c+g-1;
if(c>=m)
{
g=g-1;
e=e-(g-(c-m));
cout<<e*n+f;
return 0;
}
return 0;
}