Jam

题目描述
Jam走进了一个迷宫,他要想走出这个迷宫,必须找到一条路径,使得这条路径是回文的
当然他可不屑于去走出这个迷宫,聪明的他一定要找出有多少种方案走出这个迷宫
在一个N*NN∗N大小的迷宫,这个迷宫全由大写字母组成
他会从左上角走到右下角,然后把所有经过的字符连成一个串,当然只能往下和往右走,问有多少种方案可以走出来
当然答案会很大,所以答案和52013145201314取模输出
输入
第一行T(1 \leq T \leq 10)T(1≤T≤10),表示TT组数据。
接下来TT组数据:
每组数据第一行为N(1 \leq N \leq 500)N(1≤N≤500)表示矩阵的行和列
接下来NN行NN列N*NN∗N个字符
输出
问有多少种方案可以走出来
样例输入
1
4
ABCD
BEFE
CDEB
GCBA
样例输出
12
提示

有1种走法是”ABCDCBA”

有1种走法是”ABCGCBA”

有4种走法是”ABEDEBA”

有6种走法是”ABEFEBA”

所以共有12=6+4+1=1种走法可行

题解
由于是正方形,从左上角与右下角同时DP,一样才能走,走到对角线停止,记录步数和一维坐标即可计算出另一维,开滚动即可。

代码

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int dp[2][505][505];
int T,n,ans,k;
char a[505][505];
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
            scanf("%s",a[i]+1);
        memset(dp[0],0,sizeof(dp[0]));
        k=1;
        ans=0;
        dp[0][1][n]=(a[1][1]==a[n][n]); 
        for (int i=2;i<=n;i++)
        {
            memset(dp[k],0,sizeof(dp[k]));
            for (int x1=1;x1<=i;x1++)
            {
                for (int x2=n;x2>=n-i+1;x2--)
                {
                    int y1=i-x1+1;
                    int y2=2*n-x2-i+1;
                    if (a[x1][y1]!=a[x2][y2]) continue;
                    dp[k][x1][x2]+=dp[k^1][x1][x2];
                    dp[k][x1][x2]+=dp[k^1][x1-1][x2];
                    dp[k][x1][x2]+=dp[k^1][x1][x2+1];
                    dp[k][x1][x2]+=dp[k^1][x1-1][x2+1];
                    dp[k][x1][x2]%=5201314;
                }
            }
            k^=1;
        }
        for (int i=1;i<=n;i++)
        {
            ans+=dp[k^1][i][i];
        }
        ans%=5201314;
        printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值