[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
解题思路
这道题数据很大,如果直接按照题目要求去构造数组肯定超时。
按照上图我们发现,按照红线可以将数据分为好多“排”。那么每一排的数据比之前多一个,也就是前r排的数据个数为
(
r
+
1
)
∗
(
r
)
/
2
(r+1)*(r)/2
(r+1)∗(r)/2那么对于编号为n的数据,我们可以找到这个数据在第几排。然后找到算出这个编号为n的数据距离当前“行”r的第一行数据的距离。我们观察发现第一行的数据的y的值总是1,x的值总是排数r,所以可以很轻松根据第n个数据与当前排的第一行的数据的距离来算出x和y的值。由于成z字形排列,所以我们需要分单双排来计算。
- 偶数排的数据与当前排的第一行的数据的距离为
n
−
(
r
−
1
)
∗
r
/
2
n-(r-1)*r/2
n−(r−1)∗r/2
- 奇数排的数据与当前排的第一行的数据的距离为
(
r
+
1
)
∗
r
/
2
−
n
(r+1)*r/2-n
(r+1)∗r/2−n
代码如下
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
int n;
cin>>n;
int row=0;
while(row*(row+1)/2 <n)
row++;
int y;
if(row%2==1){
y=row*(row+1)/2-n+1;
}else{
y=n-(row-1)*row/2;
}
int x=row+1-y;
cout<<y<<"/"<<x<<endl;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)