Cantor表

16 篇文章 0 订阅
13 篇文章 0 订阅

描述

现代数学的著名证明之一是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≤N≤10000000)

输出

输出:表中的第N项

样例输入

7

样例输出

1/4

[分析]题目很简单,规律也不难找到。这类题目其实是数学游戏,在编码之前应该先算一算。 用模拟填表的方法也可以,但数学方法更有意思,求解能力也更强。不难看出,第K个斜行("/"方向)上 每个分数的分子分母之和为K+1,而表的填充顺序正是依次填写每个斜行,因此先算出第N项所在的斜行K。

显然K是满足N<=1+2+3+...+K  (1)的最小数。
显然当K为奇数时,分母为N-(1+2+3+..+K-1),K为偶数时分子为N-(1+2+3+..+K-1)。
找K显然可以递推,但是没有意思,我们应该锻炼自己的数学能力,解出不等式(1)。
不等式同解变形为:(K+1)*K>=N*2,  K*K+K-N*2>=0
解不等式,取正数区间,得 K>=(-1+sqrt(1+8*N))/2。
例如N=7时K>=(-1+sqrt(1+7*8))/2=3.275
故K=4,分子分母之和为K+1=5,因为K是偶数,分子为N-(1+2+3)=1,故分母为5-1=4

#include<stdio.h>
#include<math.h>
#include<cstring>
int main()
{
  float f;
  int N,n,zi,mu;
  while(~scanf("%d",&N))
  {
      f=(-1+sqrt(1+8*N))/2;
      n = (int)f;
      if(f - (float)n != 0)
        n +=1;
       if(n%2 == 0)
      {
          zi = N - (n-1)*n/2;
           mu = n+1-zi;
      }
   else
     {
         zi = n*(n+1)/2 -N + 1;
         mu = n+1-zi;
      }
     printf("%d/%d",zi,mu);
  }
  return 0;
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值