现代数学的著名证明之一是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,…

样例输入 Sample Input
7
样例输出 Sample Output
1/4
分析:按照斜线分类,第一条斜线有1个数,第2条有2个数,····这样记前条斜线有s个数,只要找到一个最小的正整数k,使得n<s(k),那么n就在第k条斜线上,再找n在斜线上的位置,s - n就是这条斜线上剩下数的个数,而n就是第(s - n - 1)个数或倒数第第(s - n - 1)个数,此时涉及到对这个k奇偶性的判断。
下面提供三种代码,思路相同,仅仅写法有点差异。
#include<cstdio>
using namespace std;
int main(){
int i, n;
while(~scanf("%d", &n)){
i = 1;
while(n > i){
n -= i;
i++;
}
if (i % 2 == 0)
printf("%d/%d\n", n, i - n + 1);
else
printf("%d/%d\n", i - n + 1, n);
}
return 0;
}
#include<cstdio>
using namespace std;
int main() {
int n;
while(~scanf("%d", &n)){
int i = 1;
while(n > (1+i)*i/2) i++;
n -= i*(i-1)/2;
if(i & 1)
printf("%d/%d\n", i - n + 1, n);
else printf("%d/%d\n", n, i - n + 1);
}
return 0;
}
#include<cstdio>
using namespace std;
int main(){
int n;
while(~scanf("%d", &n)){
int k = 1, s = 0;
while(1){
s += k;
if(s >= n){
if(k & 1) printf("%d/%d\n", s - n + 1, k - s + n);
else printf("%d/%d\n", k - s + n, s - n + 1);
break;
}
k++;
}
}
return 0;
}