zoukankan      html  css  js  c++  java
  • HDOJ_ACM_小兔的棋盘

    Problem Description
    小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点(0,0)走到终点(n,n)的最短路径数是C(2n,n),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧!
     
    Input
    每次输入一个数n(1<=n<=35),当n等于-1时结束输入。
     
    Output
    对于每个输入数据输出路径数,具体格式看Sample。
     
    Sample Input
    1
    3
    12
    -1
     
    Sample Output
    1 1 2
    2 3 10
    3 12 416024
    View Code
     1 //h(n) = h(n-1)*(4n-2)/(n+1)
     2 #include <stdio.h>
     3 int a[40][100];
     4 void catalan()
     5 {
     6     //initializing the begin of the array
     7     //circulate from 2 to 35, for each, multiple (4n-2) and divide(n+1)
     8     //care about initializing the carry and length, and don't forget make a[][0] = length
     9     int carry, remainder,length, i, j;
    10     a[1][0] = 1;
    11     a[1][1] = 2;
    12     length = 1;
    13     for (i = 2; i <= 35; i++)
    14     {
    15         //multipling (4n-2)
    16         carry = 0;
    17         for (j = 1; j <= length; j++)
    18         {
    19             carry += a[i - 1][j] * (4 * i - 2);
    20             a[i][j] = carry % 10;
    21             carry /= 10;
    22         }
    23         while (carry)
    24         {
    25             a[i][++length] = carry % 10;
    26             carry /= 10;
    27         }
    28         //dividing (n+1)
    29         remainder = 0;
    30         for (j = length; j >= 1; j--)
    31         {
    32             remainder = remainder * 10 + a[i][j];
    33             a[i][j] = remainder / (i + 1);
    34             remainder = remainder % (i + 1);
    35         }
    36         while (!a[i][length])
    37         {
    38             length--;
    39         }
    40         a[i][0] = length;
    41     }
    42 }
    43 int main()
    44 {
    45     int n, count, i;
    46     catalan();
    47     count = 1;
    48     while (scanf("%d", &n) != EOF && n != -1)
    49     {
    50         //formatting printing
    51         printf("%d %d ", count++, n);
    52         for (i = a[n][0]; i >= 1;i--)
    53             printf("%d", a[n][i]);
    54         puts("");
    55     }
    56     return 0;
    57 }

    Key points

    firstly, it said that the number of 'up' is always larger than the number of 'right', or always smaller. Consequestly, it's double of the catalan. you will find that just change the begin number, then you will get the right answer. 

    secondly, the above program is designed by getting the results in advance, then I finish other program which is designed by getting the result according the input. For this question, I can't find any difference. The code is as follow.

    View Code
     1 //h(n) = h(n-1)*(4n-2)/(n+1)
     2 #include <stdio.h>
     3 int a[40][100];
     4 int main()
     5 {
     6     int carry, remainder,length, i, j, count, n;
     7     count = 1;
     8     a[1][0] = 1;
     9     a[1][1] = 2;
    10     length = 1;
    11     while (scanf("%d", &n) != EOF && n != -1)
    12     {
    13         a[1][0] = 1;
    14         a[1][1] = 2;
    15         length = 1;
    16         for (i = 2; i <= n; i++)
    17         {
    18             //multipling (4n-2)
    19             carry = 0;
    20             for (j = 1; j <= length; j++)
    21             {
    22                 carry += a[i - 1][j] * (4 * i - 2);
    23                 a[i][j] = carry % 10;
    24                 carry /= 10;
    25             }
    26             while (carry)
    27             {
    28                 a[i][++length] = carry % 10;
    29                 carry /= 10;
    30             }
    31             //dividing (n+1)
    32             remainder = 0;
    33             for (j = length; j >= 1; j--)
    34             {
    35                 remainder = remainder * 10 + a[i][j];
    36                 a[i][j] = remainder / (i + 1);
    37                 remainder = remainder % (i + 1);
    38             }
    39             while (!a[i][length])
    40             {
    41                 length--;
    42             }
    43             a[i][0] = length;
    44         }
    45         printf("%d %d ", count++, n);
    46         for (i = a[n][0]; i >= 1;i--)
    47             printf("%d", a[n][i]);
    48         puts("");
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    netty入门
    zookeeper安装
    nginx
    链式调用方法的实现原理和方法
    UI设计篇·入门篇·简单动画的实现,为布局设置动画,用XML布置布局动画
    UI设计篇·入门篇·简单动画的实现,透明动画/旋转动画/移动动画/缩放动画,混合动画效果的实现,为动画设置监听事件,自定义动画的方法
    UI设计篇·入门篇·绘制简单自定义矩形图/设置按钮按下弹起颜色变化/设置图形旋转
    XML文档的生成和解析操作方法
    ListView的基本使用方法和RecyclerView的基本使用方法
    Fragment的粗浅理解
  • 原文地址:https://www.cnblogs.com/chuanlong/p/2759532.html
Copyright © 2011-2022 走看看