如下数列,第一项是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 #include <stdio.h>
 2 int main()
 3 {
 4     int n;
 5     while(scanf("%d", &n) == 1)
 6     {
 7         int k = 1, s = 0;
 8         for(; ; )
 9         {
10             s += k;
11             if(s >= n)    //s为k条斜线上数的总和
12             {
13                 if(k%2 == 1)    printf("%d/%d\n", s-n+1, k-s+n); //表示输出第k斜线倒数第s-n+1项
14                 else            printf("%d/%d\n", k-s+n, s-n+1); //表示输出第k斜线正数第k-(s-n+1)+1项,即k-s+n项
15                 break;
16             }
17             k++;
18         }
19     }
20     return 0;
21 }
View Code

分析:
  1.数表按斜线分类,第1条斜线有1个数,第2条斜线有2个数……第i条斜线有i个数,这样,前i条斜线一共有S(k)=1+2+3+…+k=k(k+1)/2个数;并且是一条斜线从上到下,另一条斜线从下到上交错排数。
  2.确定n所在斜线:只要找到一个最小的正整数k,使得n<=S(k),那么n就是第k条斜线上的倒数第S(k)-n+1个元素(最后一个元素是倒数第一个元素,而不是倒数第零个元素);则第k条斜线的倒数(k为奇数时,第k斜线倒序)第i个元素是i/(k+1-i),正数(k为偶数时,第k斜线正序)第i个元素是(k+1-i)/i。

方法二:

 1 #include <stdio.h>
 2 #include <math.h>
 3 int main()
 4 {
 5     int n;
 6     while(scanf("%d", &n))
 7     {
 8         int k = (int)floor((sqrt(8.0*n+1)-1) / 2-1e-9) + 1;    //使用floor函数避免浮点误差
 9         int s = k*(k+1) / 2;    //s为k条斜线上数的总和
10         if(k%2 == 1)    printf("%d/%d\n", s-n+1, k-s+n);    //表示输出第k斜线倒数第s-n+1项
11         else            printf("%d/%d\n", k-s+n, s-n+1);    //表示输出第k斜线正数第k-(s-n+1)+1项,即k-s+n项
12     }
13     return 0;
14 }
View Code

分析:
  1.利用代数,n<=k*(k+1)/2,k*k+k-2n>=0,(k-(sqrt(8.0*n+1)-1)/2)*(k-(-sqrt(8.0*n+1)-1)/2)>=0,注意到k-(-sqrt(8.0*n+1)-1)/2总是正数,则k>=(sqrt(8.0*n+1)-1)/2;换言之,可以直接求出则k=(sqrt(8.0*n+1)-1)/2。
  2.floor()函数,其功能是“向下取整”,或者说“向下舍入”,即取不大于x的最大整数(与“四舍五入”不同,下取整是直接去掉小数部分);
  3.指数形式:由于计算机输入或输出时,无法表示上角或下角,规定以字母e或E代表以10为底的指数;注意:e或E之前必须有数字,e或E后面必须是带符号的十进制整数,长度最大为3位,正数时可不写+号。

方法三:

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int n;
 5     while (scanf("%d", &n) == 1)
 6     {
 7         int k = 1;
 8         while (k < n)    //k为第n项所在行数,循环的意义为所求数在第k条斜线第n项
 9         {
10             n -= k;        //n减去第k条斜线上的数
11             k++;
12         }
13         if (k%2 == 1)    printf("%d/%d\n", k+1-n, n); //表示输出第k斜线倒数第(k-n)+1项
14         else            printf("%d/%d\n", n, k+1-n); //表示输出第k斜线正数第n项
15     }
16     return 0;
17 }
View Code

分析:

  用n减去前k条斜线上的个数后再和第k条斜线上个数相比即得所求数位置。

 posted on 2016-03-28 20:21  tostring_char  阅读(548)  评论(0编辑  收藏  举报