來源:《算法競賽入門經典》例題5.4.1
題目:現代數學的著名證明之一是Georg Cantor證明了有理數是可枚舉的。他是用下面這一張表來證明這一命題的: 第一項是1/1,第二項是是1/2,第三項是2/1,第四項是3/1,第五項是2/2,……。輸入n,輸出第n項。
樣例輸入:
3
14
7
12345
樣例輸出:
2/1
2/4
1/4
59/99
分析:
數表提示我們按照斜線分類。第1條斜線有1個數,第2條有2個數,第3條有3個數……第k條有k個數。這樣,前k條斜線一共有S=1+2+3+……+k個數。
第n項在哪條斜線上呢?只要找到一個最小的k,使得S≥n,那么第n項就是第k條斜線上倒數第S-n+1個數(最后一個元素是倒數第1個元素,而不是倒數第0個元素)。
而k的奇偶決定着第k條斜線上數的順序:若k是奇數,第k條斜線上倒數第i個元素是i/(k+1-i);若k是偶數,第k條斜線上倒數第i個元素是(k+1-i)/i。
源碼:
#include<stdio.h> int main() { int n,k,s; //前k挑斜線一共s個數 while(scanf("%d",&n) == 1) { k=0; s=0; while(s<n) //找到最小的k使得s>=n { k++; s+=k; } if(k%2==1) //k的奇偶決定着斜線上數的順序,n是第k條斜線上倒數第s-n+1個數 printf("%d/%d\n",s-n+1,k+n-s); //若k是奇數,第k條斜線上倒數第i個元素是i/(k+1-i) else printf("%d/%d\n",k+n-s,s-n+1); //若k是偶數,第k條斜線上倒數第i個元素是(k+1-i)/i } return 0; }