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