Cantor表
链接:https://ac.nowcoder.com/acm/problem/16785
来源:牛客网
题目描述
现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的:
我们以Z字形给上表的每一项编号。第一项是1/1,然后是1/2,2/1,3/1,2/2,…
输入描述:
整数N(1≤N≤10000000)
输出描述:
表中的第N项
示例1
输出
复制1/4
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<cmath> using namespace std; int a[10000010],b[10000010]; int main() { int n; cin >> n; a[1] = 1; b[1] = 1; int right = 1;int left = 0; for (int i = 2; i <= 10000000; i++) { if (right == 1) { a[i] = a[i - 1] + 1; if (b[i - 1] == 1) { right = 0; left = 1; b[i] = 1; } if(b[i-1]!=1) { b[i] = b[i - 1] - 1; } } else if (left == 1) { b[i] = b[i - 1] + 1; if (a[i - 1] == 1) { right = 1; left = 0; a[i] = 1; if (i == 3) { i++; b[i] = 3; a[i] = 1; } } if(a[i-1]!=1) a[i] = a[i - 1] - 1; } } cout << b[n]<<"/"<<a[n] << endl; while (1); }
遇到的问题:在i=3的时候这是个特殊情况,但被我单独拿出来处理。
解题过程:先是找规律,然后遇见这种有表的题目,便采用列表法,全部枚举出来。
感悟:牺牲空间复杂度来提高时间复杂度,说明这个方法不完美,但是这却是避无可避的