洛谷P1014-Cantor表

版权声明:如果是我原创的文章,请转载时,注明是来自我的转帖,加上我帖子的地址。谢谢! https://blog.csdn.net/mengdicfm/article/details/83004088

题目描述

现代数学的著名证明之一是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/11,然后是1/2,2/1,3/1,2/2,1/3,…
输入输出格式
输入格式:

整数N(1≤N≤10000000)

输出格式:

表中的第N项

扫描二维码关注公众号,回复: 4164812 查看本文章

输入输出样例
输入样例#1:

7

输出样例#1:

1/4

解题思路:
可以把原来的数据顺时针方向旋转45°。这样所有的数据就是一个很规则的三角形了,每行开头的第一个数的分子都是行号n,分母都是1,每行最后一个数字分子是1,分母是n。第1行就一个数字1/1。第n行(n为奇数时),数字按照n/1,n-1/2,……,2/n+1-2,1/n+1-1这样输出。第n行(n为偶数时),数字按照1/n+1-1,2/n+1-2……n-1/2,n/1这样输出。想要找到第K项数据,先要求出n。
当1+2+3……+n>=k,1+2+3……+(n-1)<k时,就找到了n的值。
然后把1+2+3……+(n-1)的和sum求出来。在第n行里从第一个数开始计数,每数一个数字,sum++。当sum=k时,就找到了数字。然后输出。

代码如下:

int k=0; //k代表是第多少项 
int n=0,sum=0,i=0,j=0;
#include<iostream>
using namespace std;
int main()
{
	cin>>k;
	//while循环找出第k个数在三角形的第n行 
	while(sum<k){
		n++;
		sum+=n;
	}
	//cout<<n<<endl;
	sum=sum-n;
	if(n%2==1) //奇数行 
	{
		for(j=n;j>=1;j--)
		{
			sum++;
			if(sum==k)
			{
				cout<<j<<"/"<<n+1-j<<endl;
				return 0;
			}
		}
	}
	else //偶数行 
	{
		for(j=1;j<=n;j++)
		{
		sum++;
		if(sum==k)
		{
			cout<<j<<"/"<<n+1-j<<endl;
			return 0;
		}	
		}	
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mengdicfm/article/details/83004088