P1875 [NOIP1999P1]Cantor表
时间: 1000ms / 空间: 131072KiB / Java类名: Main
描述
现代数学的著名证明之一是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,…
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,…
输入格式
整数N(1≤N≤10000000)
输出格式
表中的第N项
测试样例1
输入
7
输出
1/4
这是一种有理数集非常常见的列法,我们考虑对角线上的元素q/p,发现q + p是一个常数。
设读入的数为 num,那么,它必然在某一条对角线上,然后我们要找到一个n,使得
n*(n+1)/2 <= num <= (n+1)(n+2)/2
num必然在第 n + 1条对角线上, 然后设 D = num - n*(n+1)/2 ,然后讨论n的奇偶性,答案就很显然了
n = 奇 D/n+2-D
n = 偶 n+2-D/D#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; int num; int main() { scanf("%d",&num); if (num == 1){ cout<<"1/1"<<endl; return 0; } for (int n = 1;n <= num;n++){ int A = n * (n + 1) / 2; int B = (n + 1) * (n + 2) / 2; if (A <= num && num <= B){ int D = num - A; if (n & 1) cout<<D<<"/"<<n + 2 - D<<endl; else cout<<n + 2 - D<<"/"<<D<<endl; break; } } return 0; }