最优对称路径

给一个n行n列的网格,每个格子里有一个1到9的数字。你需要从左上角走到右下角,其中每一步只能往上、下、左、右四个方向之一走到相邻格子,不能斜着走,也不能走出网格,但可以重复经过一个格子。为了美观,你经过的路径还必须关于“左下-右上”这条对角线对称。你的任务是统计所有合法路径中,数字之和最小的路径有多少条。


这道题在学校oj上数据出得比较小,但对于我这种渣渣来说还是还是需要好好考虑的。


思路:网格的左上角和右下角同时往中间搜,搜到同一个点,不过搜索的时候注意对称。

这个对称是左上角的网格往右搜,那么右下角的网格就往上搜;左上角的网格往下搜,那右下角的网格就往左搜;同理可知其它方向。

每搜索出一条对称路径便比对是否最优。

因为可以重复经过一个格子,四个方向的搜索就会出现无限搜索的情况((1,1)→(1,2)→(1,1)→……等情况),这个问题卡了很久还是没有好的解决方法。最终通过记录路径上数字之和来终止这种情况。

#include<iostream>
#include<string.h>
using namespace std;
int a[205][205];
int t;
long long mmin;
long long no=0;
void dfs(int a1,int b1,int a2,int b2,long long sum)
{
    if(a1==a2&&b1==b2)
    {
        if(sum+a[a1][b1]==mmin) 
        {
            no++;
        }
        else
        if(sum+a[a1][b1]<mmin)
        {
            mmin=sum+a[a1][b1];
            no=1;
        }
    }
    else
    {
        sum+=a[a1][b1]+a[a2][b2];
        if(sum<mmin)
        {
            if(a1+1<=t)
            dfs(a1+1,b1,a2,b2-1,sum);
            if(b1+1<=t)
            dfs(a1,b1+1,a2-1,b2,sum);

            if(a1-1>0)
            dfs(a1-1,b1,a2,b2+1,sum);
            if(b1-1>0)
            dfs(a1,b1-1,a2+1,b2,sum);
        }
    }
}

int main()
{
    int i,j;
    while(1)
    {
        cin>>t;
        if(t==0) break;
        memset(a,0,sizeof(a));
        mmin=1000000009;
        no=0;
        for(i=1;i<=t;i++)
            for(j=1;j<=t;j++) cin>>a[i][j];
        dfs(1,1,t,t,0);
        cout<<no%1000000009<<endl;
    }
    return 0;
}

学校oj上数据小,这样能过,数据大了这题这样做应该就超时了。

我暂时只能做到这了。

链接是大神写的这道题的题解:http://blog.csdn.net/talak/article/details/8075223


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值