原题链接:https://www.luogu.com.cn/problem/P1014
Cantor表
题目描述
现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的:
1/11/11/1 , 1/21/21/2 , 1/31/31/3 , 1/41/41/4, 1/51/51/5, …
2/12/12/1 , 2/22/22/2 , 2/32/32/3, 2/42/42/4, …
3/13/13/1 , 3/23/23/2, 3/33/33/3, …
4/14/14/1, 4/24/24/2, …
5/15/15/1, …
…
我们以 Z 字形给上表的每一项编号。第一项是 1/11/11/1,然后是 1/21/21/2,2/12/12/1,3/13/13/1,2/22/22/2,…
输入格式
整数NNN(1≤N≤1071 \leq N \leq 10^71≤N≤107)。
输出格式
表中的第 NNN 项。
输入输出样例
输入 #1
7
输出 #1
1/4
题解
显然,每斜排的长度依次递增,我们可以枚举最小的满足i×(i+1)≥Ni\times (i+1)\ge Ni×(i+1)≥N的iii就能找到第NNN个数在第iii排,再根据同一排的分数分子分母之和为i+1i+1i+1,并判断一下iii的奇偶性,即可找到第NNN个数。
代码
为了编写这个程序,我们需要先用forforfor循环枚举1∼N1\sim N1∼N的所有整数找到iii(事实上可以直接在N\sqrt{N}N附近找,但是为了练习循环语句,姑且用这个不那么快的办法)。
PythonPythonPython的forforfor循环可以直接枚举一个集合中的元素,而不是像CCC++那样先枚举下标,再通过下标访问对应元素。当然,在这里我们并不需要这么复杂,直接枚举数就行了,可以用函数range(start,end,step)range(start,end,step)range(start,end,step)返回的一个数组来规定一个枚举的范围,startstartstart为枚举的起点(不填时默认为000),endendend是必填参数,为枚举的终点+1+1+1(即range(3)=[0,1,2]range(3)=[0,1,2]range(3)=[0,1,2]),而stepstepstep为数之间的间隔,当我们需要使用stepstepstep参数时,必须将startstartstart参数也加上,否则range(end,step)range(end,step)range(end,step)函数会返回一个end∼stepend\sim stepend∼step的数组。
判断语句与CCC++区别不大,但是习惯CCC++而又初学PythonPythonPython的人(比如我)很容易漏掉冒号。
PythonPythonPython的输出函数也非常强大,它可以直接以对应的数据类型输出数据而不需要像CCC++那样让编程者通过%d
、%c
这样的符号来人为规定。同时,它还可以设置间隔符sepsepsep,默认间隔符为空格,如果不想要间隔,可以设为sep=''
,即间隔符为空,设置其他间隔符类似,如sep=','
。
代码
n=int(input())
for i in range(1,n):
if i*(i+1)/2>=n:
break
a=int(n-i*(i-1)/2)
if i%2==0:
print(a,'/',i+1-a)
else:
print(i+1-a,'/',a,sep='')