洛谷 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;
}

谢谢--zhengjun

posted @ 2022-06-10 18:32  A_zjzj  阅读(30)  评论(0编辑  收藏  举报