题目
现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的:
1/1 , 1/2 , 1/3 , 1/4, 1/5, …
2/1, 2/2 , 2/3, 2/4, …
3/1 , 3/2, 3/3, …
4/1, 4/2, …
5/1, …
…
我们以 Z 字形给上表的每一项编号。第一项是 1/1,然后是 1/2,2/1,3/1,2/2,…
输入: k 按题排序所在位置
输出:m/n 第k项的编号
求解思路
为了便于观察把题目中表的形式改写一下:
不难发现当处于偶数行时序号向右递增,奇数行序号向左递增。而且第n行有n项 ,这样可以得到前n项的和为 a(n) = n(n+1)/2,通过前n项和可以得到k所在行位置。再通过k-a(n-1),得到k所在行的具体位置。
以k=7为例:
因为 a(3)<7 <=a(4) 所以 第7项在第4行 可用row表示
7-a(3) = 1 即在第4行第1个位置 可用col表示
每一行都等于(1+row)
发现当k = 7时, 1可用col表示(即使在本行递增依旧成立),所以row = (1+row)-col
可得结果为 col/(row-col+1)
上述为偶数行个例,当为奇数行,只需改变下顺序即可。
#include<iostream>
using namespace std;
int fun(int x)
{
return x*(x+1)/2;
}
int main()
{
int k,n,row,col;
cin >> k;
int i = 0;
while(!(k>fun(i) && k<=fun(i+1)))
{
i++;
}
row = i + 1;
col = k - fun(i);
if(row%2 == 0)
{
cout << col << "/" << row-col+1 << endl;
}
else
{
cout << row-col+1 << "/" << col << endl;
}
return 0;
}