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. 



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+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
", x-1, y );  //此处计算的x有一步之差,没有处理bug,因为让x-1就等于正确的坐标
        else  
        {  
            int kk;  
            kk=(n+1)/2; 
            kk=kk-dd;
            printf("%d %d
", x-1+kk, y+kk );  //如果该圈数不是最外圈,坐标加上外面的圈数。
        }  
    }  
    return 0;  
}  
原文地址:https://www.cnblogs.com/yspworld/p/4248695.html