题目描述
现代数学的著名证明之一是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 Z 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 ≤ 10000000 1\leq N\leq 10000000 1≤N≤10000000)
输出格式
表中的第 N N N项
输入输出样例
输入 #1
7
输出 #1
1/4
思路
这就是一道找规律的题目,首先我把斜着的看成一组:
第一组
1
/
1
1/1
1/1
第二组
1
/
2
1/2
1/2 ,
2
/
1
2/1
2/1
第三组
1
/
3
1/3
1/3 ,
2
/
2
2/2
2/2, ,
3
/
1
3/1
3/1
…
…
……
……
这样这要找出
N
N
N在那一组就好了。
另外,再找
N
N
N是第几组的时候,最好用二分。
找到之后,就判断奇偶,算出来就可以了。
代码
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
register int f=1,x=0;register char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n;
int main()
{
n=read();
register int l=0,r=n,m;
while(l+1<r)
{
m=(l+r)>>1;
if(m*(m+1)/2<n)l=m;
else r=m;
}
l++;
register int a=n-l*(l-1)/2;
if(l%2==0)//奇偶判断
printf("%d/%d",a,l+1-a);
else
printf("%d/%d",l+1-a,a);
return 0;
}