洛谷 P1014Cantor表题解--zhengjun
题目描述
现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的:
\(1/1\) , \(1/2\) , \(1/3\) , \(1/4\) , \(1/5\) , \(…\)
\(2/1\) , \(2/2\) , \(2/3\) , \(2/4\) , \(…\)
\(3/1\) , \(3/2\) , \(3/3\) , \(…\)
\(4/1\) , \(4/2\) , \(…\)
\(5/1\) , \(…\)
… 我们以\(Z\)字形给上表的每一项编号。第一项是\(1/1\),然后是\(1/2\),\(2/1\),\(3/1\),\(2/2\),…
输入格式
整数\(N\)(\(1\leq N\leq 10000000\))
输出格式
表中的第\(N\)项
输入输出样例
输入 #1
7
输出 #1
1/4
思路
这就是一道找规律的题目,首先我把斜着的看成一组:
第一组\(1/1\)
第二组\(1/2\) , \(2/1\)
第三组\(1/3\) , \(2/2\), ,\(3/1\)
\(……\)
这样这要找出\(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;
}