Pascal's Travels HDU

来源:互联网 发布:vim for mac 编辑:程序博客网 时间:2024/06/05 07:57


An n x n game board is populated with integers, one nonnegative integer per square. The goal is to travel along any legitimate path from the upper left corner to the lower right corner of the board. The integer in any one square dictates how large a step away from that location must be. If the step size would advance travel off the game board, then a step in that particular direction is forbidden. All steps must be either to the right or toward the bottom. Note that a 0 is a dead end which prevents any further progress. 


Consider the 4 x 4 board shown in Figure 1, where the solid circle identifies the start position and the dashed circle identifies the target. Figure 2 shows the three paths from the start to the target, with the irrelevant numbers in each removed. 


Figure 1


Figure 2
Input
The input contains data for one to thirty boards, followed by a final line containing only the integer -1. The data for a board starts with a line containing a single positive integer n, 4 <= n <= 34, which is the number of rows in this board. This is followed by n rows of data. Each row contains n single digits, 0-9, with no spaces between them. 
Output
The output consists of one line for each board, containing a single integer, which is the number of paths from the upper left corner to the lower right corner. There will be fewer than 2^63 paths for any board. 
Sample Input
423311213123131104333212131232212051110101111111111110111101-1
Sample Output
307          Brute force methods examining every path will likely exceed the allotted time limit. 64-bit integer values are available as "__int64" values using the Visual C/C++ or "long long" values using GNU C/C++ or "int64" values using Free Pascal compilers. 
Hint
Hint


这道题意思是 一个n x n游戏板填充整数,一个非负整数每平方。目标是沿着从左上角到右下角的任何合法路线行进。任何一个方块中的整数决定了距离该位置的距离有多大。如果步距大大提升游戏板的距离,那么禁止这个特定方向的步骤。所有步骤必须在右侧或底部。请注意,0是一个死胡同,防止任何进一步的进展。
考虑图1所示的4 x 4板,其中实心圆标识起始位置,虚线圆标识目标。图2显示了从起始到目标的三个路径,每个路径中的不相关数字被删除。
输入包含一到三十个单板的数据,后跟一个仅包含整数-1的最后一行。电路板的数据以包含单个正整数n的行开始,4 <= n <= 34,即该单板中的行数。这之后是n行数据。每行包含n个单数位,0-9,它们之间没有空格。
输出由每个单板的一行组成,包含一个整数,即从左上角到右下角的路径数。任何董事会将不到2 ^ 63个路径  

                                              

方法1:2代表它只能向右走2步或向下走2步,用dp用来保存路径,最后输出dp[n-1][n-1]即可。

方法2:用深搜做if(dp[x][y]  ||  a[x][y]==0)      return dp[x][y],    

dp[x][y]+=dfs(x+a[x][y],y)  dp[x][y]+=dfs(x,y+a[x][y]);


方法1:

#include<stdio.h>
#include<string.h>
char a[50][50];
__int64 dp[100][100];
int main()
{
    int n,i,j;
    while(~scanf("%d",&n)&&n!=-1)
    {
        memset(dp,0,sizeof(dp));
        for(i=0; i<n; i++)
            scanf("%s",a[i]);
        dp[0][0]=1;
        for(i=0; i<n; i++)
        {
            for(j=0; j<n; j++)
            {
                int t=a[i][j]-'0';
                if(i==n-1&&j==n-1)
                    break;
                dp[i+t][j]+=dp[i][j];//向右
                dp[i][j+t]+=dp[i][j];//向下
            }
        }
        printf("%I64d\n",dp[n-1][n-1]);
    }
    return 0;
}

方法2:



#include<stdio.h>
#include<string.h>
__int64 dp[50][50];
int a[50][50],n;
__int64 dfs(int x,int y)
{
    if(x<0||y<0||x>=n||y>=n)
        return 0;
    if(dp[x][y]||a[x][y]==0)
        return dp[x][y];
    dp[x][y]+=dfs(x+a[x][y],y);
    dp[x][y]+=dfs(x,y+a[x][y]);
    return dp[x][y];
}
int main()
{
    while(~scanf("%d",&n)&&n!=-1)
    {
        int i,j;
        memset(dp,0,sizeof(dp));
        for(i=0; i<n; i++)
            for(j=0; j<n; j++)
                scanf("%1d",&a[i][j]);
        dp[n-1][n-1]=1;
        printf("%lld\n",dfs(0,0));
    }
    return 0;
}

#include<stdio.h>#include<string.h>char a[50][50];__int64 dp[100][100];int main(){    int n,i,j;    while(~scanf("%d",&n)&&n!=-1)    {        memset(dp,0,sizeof(dp));        for(i=0; i<n; i++)            scanf("%s",a[i]);        dp[0][0]=1;        for(i=0; i<n; i++)        {            for(j=0; j<n; j++)            {                int t=a[i][j]-'0';                if(i==n-1&&j==n-1)                    break;                dp[i+t][j]+=dp[i][j];//向右                dp[i][j+t]+=dp[i][j];//向下            }        }        printf("%I64d\n",dp[n-1][n-1]);    }    return 0;}#include<stdio.h>#include<string.h>__int64 dp[50][50];int a[50][50],n;__int64 dfs(int x,int y){    if(x<0||y<0||x>=n||y>=n)        return 0;    if(dp[x][y]||a[x][y]==0)        return dp[x][y];    dp[x][y]+=dfs(x+a[x][y],y);    dp[x][y]+=dfs(x,y+a[x][y]);    return dp[x][y];}int main(){    while(~scanf("%d",&n)&&n!=-1)    {        int i,j;        memset(dp,0,sizeof(dp));        for(i=0; i<n; i++)            for(j=0; j<n; j++)                scanf("%1d",&a[i][j]);        dp[n-1][n-1]=1;        printf("%lld\n",dfs(0,0));    }    return 0;}