[smoj 1022]位置

题目描述

输入格式  1022.in

第一行:1个奇数N。
第二行:1个整数A。 (0 < A <= N*N)

输出格式  1022.out

一个整数,表示编号A地砖的位置编码。

输入样例  1022.in
5
20
输出样例  1022.out

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值