/*
Cantor的数表:
如下列数,第一项是1/1,第二项是1/2,第三项是2/1,第四项是3/1,第五项是2/2,......。
输入n,输出第n项。
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
(本质上是一个折线)
输入:
3
14
7
12345
输出:
2/1
2/4
1/4
59/99
关键:
这是一个折线,需要确定折线的走向公式与数字之间的关系,用数字反映折线
第1条折线 1个元素
2 3
n, =(n+1)*n/2个元素
确定n是在 <=s(k) = (k+1)*k/2的最小k,第k条斜线上,然后n是该斜线上倒数第s(k)+1-n个元素,因为最后一个元素是倒数第一个元素i/(k+1-i)。属于数学归纳法
*/
/*
关键:
1 确定n是在 <=s(k) = (k+1)*k/2的最小k,第k条斜线上,然后n是该斜线上倒数第s(k)+1-n个元素,因为最后一个元素是倒数第一个元素i/(k+1-i)。属于数学归纳法
2 if(k % 2 != 0)//奇数从下向上,上面大,下面的分母应该大,用k+1-i,倒数第一是最大分母,例如i=1,k=5,第五斜线最后一个元素分母为5
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
*/
#include <stdio.h>
#include <stdlib.h>
void cantor(int n)
{
//枚举求斜线k的值
int k;
for(k = 1 ; ;k++)
{
if(n <= (k+1)*k/2 && n > (k-1)*k/2)
{
break;
}
}
int iSum = (k+1)*k/2;
int i = iSum + 1 -n;
if(k % 2 != 0)//奇数不需要转换,奇数从下向上,上面大,下面的分母应该大,用k+1-i,倒数第一是最大分母,例如i=1,k=5,第五斜线最后一个元素分母为5
{
printf("%d/%d\n",i,(k+1-i));
}
else//偶数斜线,从上向下,最后一个元素分母最小,因此分母为i
{
printf("%d/%d\n",(k+1-i),i);
}
}
int main(int argc,char* argv[])
{
int n;
while(EOF != scanf("%d",&n))
{
cantor(n);
}
system("pause");
return 0;
}
算法竞赛入门经典:第五章 基础题目选解 5.9 Cantor数
最新推荐文章于 2023-08-03 22:38:48 发布