螺旋方阵

Problem Description

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

1 2 3 4 5 

------------------------ 

1 | 21 22 23 24 25 

2 | 20 7 8 9 10 

3 | 19 6 1 2 11 

4 | 18 5 4 3 12 

5 | 17 16 15 14 13 

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.

Input

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.

Output

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.

Sample Input

3
3 9
5 21
5 16

Sample Output

1 3
1 1
5 2

Author

HYNU

# include<cstdio>
# include<iostream>
using namespace std;
int main()
{
    //freopen("a.txt","r",stdin);
    int t;
    cin>>t;
    while(t--)
    {
        int i,n,m,flag=1,x,r,c,cnt,mul=0,y=1,z=0;
        __int64 sum;
        cin>>n>>m;
        for(i=1;i<=n;i+=2)                              //判断当前数在螺旋矩阵的那一层;
        {
            sum=i*i;
            if(sum==m)
            {
                cout<<1+(n-i)/2<<' '<<n-(n-i)/2<<endl;
                y=0;
                break;
            }
            if(sum>m)
            {
                x=i;
                break;
            }
        }
        r=1+(n-i)/2,c=n-(n-i)/2;                       //赋当前层最大数的坐标。即如果是第n层就赋n*n<span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 1.4em;">的坐标;</span>
        sum-=m;                                        //计算反向循环需要走多少步;
        x-=1;
        for(i=1;i<=sum;i++)                            //开始反向螺旋,计算m点的坐标;
        {
            cnt=i-mul;
            if(flag==1)                                //flag的值控制r,c的变化;x的值随着层数的减少也相应减少;
            {
                c=c-1;         //cout<<flag<<' ';
                if(cnt==x)
                {
                    flag=flag+1;
                    mul+=x;
                }
                continue;
            }
            if(flag==2)
            {
                r=r+1;       //cout<<flag<<' ';
                if(cnt==x)
                {
                    flag=flag+1;
                    mul+=x;
                    if(!z)    z=1;                                 当反向循环到第二层的时候,x的值没换两次方向变化一次;
                    else      x-=1;
                }
                continue;
            }
            if(flag==3)
            {
                c=c+1;       //cout<<flag<<' ';
                if(cnt==x)
                {
                    flag=flag+1;
                    mul+=x;
                    x-=1;
                }
                continue;
            }
            if(flag==4)
            {
                r=r-1;       //cout<<flag<<' ';
                if(cnt==x)
                {
                    flag=1;
                    mul+=x;
                }
                continue;
            }
        }
        if(y)    cout<<r<<' '<<c<<endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值