zoukankan      html  css  js  c++  java
  • ACM学习历程—广东工业大学2016校赛决赛-网络赛C wintermelon的魔界寻路之旅(最短路 && 递推)

    题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=2

    题目由于要找对称的路径,那么狠明显可以把右下角的每一块加到左上角对应的每一块上。然后就变成从左上角走到对角线的最短路径的个数。

    先跑一遍最短路径得到p(i, j)从起点到(i, j)的最短路径。

    然后就是找最短路径的个数。显然cnt(i, j)是它周围点能通过最短路径到它的cnt的和。这一处可以使用记忆化搜索来完成。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <vector>
    #include <string>
    #define LL long long
    #define MOD 1000000009
    
    using namespace std;
    
    const int maxN = 105;
    int xx[] = {-1,  1,  0,  0};
    int yy[] = { 0,  0, -1,  1};
    int n, a[maxN][maxN], mi;
    int p[maxN][maxN];
    int cnt[maxN][maxN];
    bool vis[maxN*maxN];
    
    void input()
    {
        scanf("%d", &n);
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j)
                scanf("%d", &a[i][j]);
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j)
                if (i+j != n-1)
                    a[i][j] += a[n-1-j][n-1-i];
        memset(p, -1, sizeof(p));
        memset(vis, false, sizeof(vis));
    }
    
    void cal()
    {
        int k, x, y, ix, iy;
        queue<int> q;
        p[0][0] = a[0][0];
        q.push(0);
        vis[0] = true;
        while (!q.empty())
        {
            k = q.front();
            q.pop();
            vis[k] = false;
            x = k/100;
            y = k%100;
            for (int i = 0; i < 4; ++i)
            {
                ix = x+xx[i];
                iy = y+yy[i];
                if (ix+iy > n-1 || ix < 0 || iy < 0) continue;
                if (p[ix][iy] == -1 || p[ix][iy] > p[x][y]+a[ix][iy])
                {
                    p[ix][iy] = p[x][y]+a[ix][iy];
                    if (!vis[100*ix+iy])
                    {
                        q.push(100*ix+iy);
                        vis[100*ix+iy] = true;
                    }
                }
            }
        }
        mi = p[0][n-1];
        for (int i = 0; i < n; ++i)
            mi = min(mi, p[i][n-1-i]);
    }
    
    int dfs(int x, int y)
    {
        if (cnt[x][y] != -1) return cnt[x][y];
        int ix, iy, all = 0;
        for (int i = 0; i < 4; ++i)
        {
            ix = x+xx[i];
            iy = y+yy[i];
            if (ix+iy > n-1 || ix < 0 || iy < 0) continue;
            if (p[ix][iy]+a[x][y] == p[x][y])
                all = (all+dfs(ix, iy))%MOD;
        }
        cnt[x][y] = all;
        return all;
    }
    
    void work()
    {
        cal();
        memset(cnt, -1, sizeof(cnt));
        cnt[0][0] = 1;
        int ans = 0;
        for (int i = 0; i < n; ++i)
            if (mi == p[i][n-1-i])
                ans = (ans+dfs(i, n-1-i))%MOD;
        printf("%d
    ", ans);
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        int T;
        scanf("%d", &T);
        for (int times = 1; times <= T; ++times)
        {
            input();
            work();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Element-UI中Upload上传文件前端缓存处理
    Puppeteer前端自动化测试实践
    javascript-高级用法
    什么是闭包?闭包的优缺点?
    浅谈网站性能之前端性能优化
    2019前端面试题汇总(主要为Vue)
    从官网学习Node.js FS模块方法速查
    这才是官方的tapable中文文档
    面试官问:JS的this指向
    开启梦幻般的webrtc之旅
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/5375151.html
Copyright © 2011-2022 走看看