sdut oj 1510 Contest02-4 Spiral

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. 

sdut oj 1510 Contest02-4 Spiral

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.

示例输入

3

3 9

5 21

5 16

示例输出

1 3

1 1

5 2

题目分析:输入t组,每组n代表是矩阵的行(==列), 再输入一个数m,输出该数在该矩阵的坐标(x, y)。
算法分析:
找规律 1.先计算出要找的那个数字在从中心往外的螺旋矩阵的第几层上
2.在该圈上的第几个位置,(先假设当前所在的圈是最外圈 )通过下标的变换移动过去
3.如果当前圈是最外圈就直接输出结果, 否则还要计算一下,此圈的外面还有几圈套着,x和y都要再加上套着的圈数输出

代码:
#include <stdio.h>  

#include <string.h>  

#include <stdlib.h>  

#include <iostream>  

#include <string>  

#include <algorithm>  

#include <math.h>  

  

using namespace std;  

  

  

int main()  

{  

    int t;  

    int i, j;  

    int n; long long m;  

    int dd, ff;  

    int a, b;  

    int x, y;  

  

    scanf("%d", &t);  

    while(t--)  

    {  

        scanf("%d %lld", &n, &m);  

        if( m==1 )  

        {  

  

            printf("%d %d\n",(n+1)/2,(n+1)/2 );  //如果m=1,输出矩阵中心的位置坐标

            continue;  

        }  

  

        for(i=1; i<=n; i++)  

        {  

            if( (i*2-1)*(i*2-1)>=m ) //这是找规律计算的结果,即是中心子矩阵的元素数和

            {  

                break;  //计算找到我们要找的那个数在第几圈上

            }  

        }  

        dd=i; //dd保存我们要找的那个数在第几圈

        ff=i-1;  

        a=(ff*2-1)*(ff*2-1);  //计算内部矩阵的数字个数和

        int len=m-a; //  计算从特定坐标开始移动的步数到达要到达的数字

  

        b=(dd-1)*2; //一个板长,移动一个b的长度,坐标就要有一个元素转换方向 

        int cnt=0;  

        int cc;  

        while(cnt<len)  

        {  

            cc=0;  

            x=2; y=dd*2-1;  

            while(cnt<len && cc<b)  

            {  

                cnt++;  

                x++;  //往下移动 y不变

                cc++;  

            }  

            cc=0;  

            while(cnt<len && cc<b)  

            {  

                cnt++;  

                y--; //往左移动 x不变

                cc++;  

            }  

            cc=0;  

            while(cnt<len && cc<b)  

            {  

                cnt++;  

                x--;  //在向上移动 y不变

                cc++;  

            }  

            cc=0;  

            while(cnt<len && cc<b)  

            {  

                cnt++;  

                y++;  //在向右移动 x不变

                cc++;  

            }  

        }  

        if(dd==((n+1)/2) )  

            printf("%d %d\n", x-1, y );  //此处计算的x有一步之差,没有处理bug,因为让x-1就等于正确的坐标

        else  

        {  

            int kk;  

            kk=(n+1)/2; 

            kk=kk-dd;

            printf("%d %d\n", x-1+kk, y+kk );  //如果该圈数不是最外圈,坐标加上外面的圈数。

        }  

    }  

    return 0;  

}  

 

你可能感兴趣的:(test)