Spiral——找规律暴力

来源:互联网 发布:2017年网络红歌 编辑:程序博客网 时间:2024/06/07 06:21

Contest02-4 Spiral

Time Limit: 1000MS Memory limit: 65536K

题目描述

Given an odd number n, we can arrange integers from 1 to n*n in the shape of a spiral. The Figure 1 below illustrates the spiral made by integers from 1 to 25. 



As we see above, each position in the spiral corresponds to a unique integer. For example, the number in row 1, column 1 is 21, and integer 16 is in row 5, column 2. Now, given the odd number n(1<=n<=32768), and an integer m(1<=m<=n*n), you should write a program to find out the position of m.

输入

The first line of the input is a positive integer T(T<=20). T is the number of the test cases followed. Each case consists of two integer n and m as described above.

输出

For each case, output the row number and column number that the given integer is in, separated by a single whitespace. Please note that the row and column number are both starting from 1.

示例输入

33 95 215 16

示例输出

1 31 15 2

提示


 题意:给出一个n * n的图,中间是1的位置,然后按照顺时针螺旋旋转,为2到n * n的位置,求任意一个数的位置坐标。

关键就是找到1的坐标,还有次对角线上的坐标,通过观察图片,可以得到:1的坐标总是n/2+1,因为n总是奇数,从1开始,沿着次对角线向右上方延伸,依次为3*3,5*5,7*7......都是奇数的平方。从1位置沿次对角线向左下方向找,依次为2*2+1,4*4+1,6*6+1.....,都是偶数的平方加1,而且,它们的坐标都可以根据1的坐标很容易地计算出来,所以以这条对角线为根本,就可以计算任何一个点的坐标了。
 

#include <iostream>  #include <stdio.h>  #include <string.h>  #include <math.h>    using namespace std;    int main()  {      int t,n,m,i,j,k,fang,x,y,x1,y1,x2,y2;      scanf("%d",&t);      while(t--)      {          scanf("%d%d",&n,&m);          int bj = 0;          x = y = n/2 + 1;          if(m == 1)          {              printf("%d %d\n",x,y);          }          else          {              for(i = 1; i <= 32767; i = i + 2)  //找到该点对应的圈数,即该点最后大于等于的上方对角线的位置            {                  if((i + 2) *( i + 2) > m && i * i <= m)                  {                      x1 = x - (i - 1)/2;                      y1 = y + (i - 1)/2;                      break;                  }              }              fang = i;              x2 = x + (i+1) /2;  //找到改圈对应的下方对角线的坐标,这样就将一个整圈分成了2个部分            y2 = y - (i+1) /2;              if(i  * i == m)              {                  printf("%d %d\n",x1,y1);                  continue;              }              else              {                  i = i +1;                  if(((fang +1)* (fang+1)) + 1 <= m)                  {                      x2 = x + i/2;                      y2 = y - i/2;                      bj = 1;                  }                  if(((fang +1)* (fang+1)) + 1 == m)                  {                      printf("%d %d\n",x2,y2);                      continue;                  }                  else                  {                      if(bj == 1)  //说明点在第二圈,即图的左边或是上边                    {                          int flag = 0;                          int aa = i * i + 1;                          for(x2--; x2 >= x1-1; x2--)  //判断是不是在左边                        {                              aa++;                              if(aa == m)                              {                                  flag = 1;                                  break;                              }                          }                          if(flag == 1)                              printf("%d %d\n",x2,y2);                          else  //不在左边,那就在上边,计算下标                        {                              x2++;                              for(y2++; y2 <= y1; y2++)                              {                                  aa++;                                  if(aa == m)                                  {                                      printf("%d %d\n",x2,y2);                                      break;                                  }                              }                          }                      }                      else  //锁定该点在图的右边或者下边                    {                          int flag = 0;                          int aa = (fang) * (fang) ;                          y1++;                          for(x1; x1 <= x2; x1++)  //判断是不是在图的右边                        {                              aa++;                              if(aa == m)                              {                                  flag = 1;                                  break;                              }                          }                          if(flag == 1)                              printf("%d %d\n",x1,y1);                          else  //不在右边,就在下边了,计算坐标                        {                          x1--;                              for(y1--; y1 > y2; y1--)                              {                                  aa++;                                  if(aa == m)                                  {                                      printf("%d %d\n",x1,y1);                                      break;                                  }                              }                          }                      }                  }              }          }      }      return 0;  }  


0 0
原创粉丝点击