题目给出如下表的一个矩阵: (红字表示行数或列数)
25 | 24 | 23 | 22 | 21 | 5 |
10 | 11 | 12 | 13 | 20 | 4 |
9 | 8 | 7 | 14 | 19 | 3 |
2 | 3 | 6 | 15 | 18 | 2 |
1 | 4 | 5 | 16 | 17 | 1 |
1 | 2 | 3 | 4 | 5 |
如表格,矩阵是从1开始盘曲的,排放规律不是很难找。
题目要求算出某个数的坐标,数据范围2*10^9,很明显不能用模拟的,这题是纯数学题,找规律题。
我们把矩阵拆开来看,每次进入上一层都会方向反转,每一层拆出来看就是:
25 24 23 22 21 20 19 18 17 10 11 12 13 14 15 16 9 8 7 6 5 2 3 4 1
这样一个三角形,把坐标也写进去就是:
(第一次发现编辑器如此蛋疼。。。制表格老是错乱!)
下面贴了图片了。
25 24 23 22 21 20 19 18 17 第5层 1.5 2.5 3.5 4.5 5.5 5.4 5.3 5.2 5.1 10 11 12 13 14 15 16 第4层 1.4 2.4 3.4 4.4 4.3 4.2 4.1 9 8 7 6 5 第3层 1.3 2.3 3.3 3.2 3.1 2 3 4 第2层 1.2 2.2 2.1 1 第1层 1.1
很快就能发现中间那个数都是在(n,n),然后向左向右都有规律的变化。
只要把这个规律描述出来就行了,注意层数的奇偶不同变化规律也会有所不同。
具体见代码:
#include <cstdio> #include <cmath> using namespace std; int main() { long long n; while (scanf("%lld", &n) && n) { long long k = ceil(sqrt(n)); if (k % 2 == 0) { if (k * k - n + 1 < n - (k - 1) * (k - 1)) printf("%lld %lld ", k, k * k - n + 1); else printf("%lld %lld ", n - (k - 1) * (k - 1), k); } else { if (k * k - n + 1 < n - (k - 1) * (k - 1)) printf("%lld %lld ", k * k - n + 1, k); else printf("%lld %lld ", k, n - (k - 1) * (k - 1)); } } return 0; }