[NOIP1999 普及组] Cantor 表
题目描述
现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的:
1 / 1 1/1 1/1 , 1 / 2 1/2 1/2 , 1 / 3 1/3 1/3 , 1 / 4 1/4 1/4, 1 / 5 1/5 1/5, …
2 / 1 2/1 2/1, 2 / 2 2/2 2/2 , 2 / 3 2/3 2/3, 2 / 4 2/4 2/4, …
3 / 1 3/1 3/1 , 3 / 2 3/2 3/2, 3 / 3 3/3 3/3, …
4 / 1 4/1 4/1, 4 / 2 4/2 4/2, …
5 / 1 5/1 5/1, …
…
我们以 Z 字形给上表的每一项编号。第一项是 1 / 1 1/1 1/1,然后是 1 / 2 1/2 1/2, 2 / 1 2/1 2/1, 3 / 1 3/1 3/1, 2 / 2 2/2 2/2,…
输入格式
整数 N N N( 1 ≤ N ≤ 1 0 7 1 \leq N \leq 10^7 1≤N≤107)。
输出格式
表中的第 N N N 项。
样例 #1
样例输入 #1
7
样例输出 #1
1/4
本题采用的枚举,直接把全部情况枚举出来。
根据题目,可以找出规律,(下表同一颜色的表示在同一组)
这个Z字型,需要你把图表顺时针旋转45°,你会发现,奇数组内顺序是从下到上,偶数组内顺序是从上到下。 每个组里面,最大的数就是它的组号,最小是1,偶数组里面每一个数的下一个,都是分子+1,分母减一。奇数组则相反。
通过以上规律就可以依次枚举出来了。
//#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int main() {
int k = 0;
//输入k的值
cin >> k;
int n1 = 1, n2 = 1, ans = 0; //n1表示分子,n2表示分母,ans表示个数
int num = 1; //组号
while (true) {
if (ans == k || k == 1)
break;
int i = 1;
for (; i <= num && ans < k; i++) {
if (num % 2 == 0) { //偶数组
n1 = i;
n2 = num - i + 1;
}
else { //奇数组
n1 = num - i + 1;
n2 = i;
}
++ans;
}
++num;
}
cout << n1 << "/" << n2 << endl;
return 0;
}
题目来自洛谷