Sicily 1694. Spiral

训练的题目

模拟题,蛇形矩阵,保证是n*n的矩阵,并且n是奇数 , 在矩阵中填数,从最中心开始填,逆时针转圈,1,2,3…………n*n。输入n,表示矩阵的大小,输入一个数字m,找出m在矩阵的哪行哪列

其实这个蛇形矩阵可以分为一圈一圈来看,要找m,可以先确定它在哪一圈

每一圈都值的范围是  [ k^2+1 , (k+2)*(k+2) ] ,其中k是奇数

看一圈的四个角,

右上角最大:  max = (k+2)*(k+2)

左上角次之:  max - (k+2) + 1

左下角再次: max - 2*(k+2) + 2

右下角 :     max - 3*(k+2) + 3

所以可以以这4个值作为一个范围,将这个圈分成4份,叫做 上行 ,  左列  ,  下行  ,  右列

这4分里面的数字是连续的,要在里面找一个值,直接扫描即可

代码写得不是很好,后来没修改了

#include <cstdio>
#include <cstring>
#define MAX 32768

typedef long long ll;
ll nn[MAX+10];
ll pos,n;

void init()
{
   memset(nn,0,sizeof(nn));
   for(ll i=1; i<=MAX+6; i+=2)
      nn[i] = i*i;
}

ll search(ll p)
{
   for(ll i=1; ; i+=2)
      if(nn[i] < p && p <= nn[i+2])
         return i;
   return -1;
}

int main()
{
   init();
   int T;
   scanf("%d",&T);
   while(T--)
   {
      scanf("%lld%lld",&n,&pos);
      if(pos == 1)
      {
         printf("%lld %lld\n",(n+1)/2 , (n+1)/2);
         continue;
      }
      ll m = search(pos);
      ll max = (m+2)*(m+2);
      ll q = (m+1)/2;

      //【 m*m+1 , (m+2)*(m+2) 】
      //找到在第q圈

      ll r , c;
      ll k;
      ll temp;

      if(pos <= max && pos > max-(m+2)+1) //上行
      {
         r = (n+1)/2 - q;
         c = (n+1)/2 + q;

         temp = max;
         for(k=c; ;k--,temp--)
            if(temp == pos)
               break;

         printf("%lld %lld\n",r,k);

      }
      else if(pos <= max-(m+2)+1 && pos > max-2*(m+2)+2 ) //左列
      {
         c = (n+1)/2 - q;
         r = (n+1)/2 - q;
         temp = max-(m+2)+1;
         for(k=r; ;k++,temp--)
            if(temp == pos)
               break;

         printf("%lld %lld\n",k,c);
      }
      else if(pos <= max-2*(m+2)+2 && pos > max-3*(m+2)+3 ) //下行
      {
         r = (n+1)/2 + q;
         c = (n+1)/2 - q;
         temp = max-2*(m+2)+2;
         for(k=c; ;k++,temp--)
            if(temp == pos)
               break;

         printf("%lld %lld\n",r,k);
      }
      else if( pos <= max-3*(m+2)+3 && pos > max-4*(m+2)+4)//右列
      {
         c = (n+1)/2 + q;
         r = (n+1)/2 + q;
         temp = max-3*(m+2)+3;
         for(k=r; ;k--,temp--)
            if(temp == pos)
               break;
         printf("%lld %lld\n",k,c);
      }
   }
   return 0;
}
原文地址:https://www.cnblogs.com/scau20110726/p/3052380.html