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.
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;
}

浙公网安备 33010602011771号