zoukankan      html  css  js  c++  java
  • hdu 1044 Collect More Jewels 搜索

    hdu 1044 Collect More Jewels 搜索
    //hdu 1044 Collect More Jewels
    //搜索
    //题意:起点 '@' 终点 '<' 宝石 'A' ~ 'J',在一定时间内
    //从起点到终点,且求出能得到最多价值是多少
    
    //思路:先用广搜求出起点、终点即所有宝石之间的最短距离
    //然后深搜
    
    #include <stdio.h>
    #include <string.h>
    
    
    #define N 55
    #define INF 1<<30
    #define eps 1e-5
    
    const int dir[2][4] = {0, -1, 0, 1, -1, 0, 1, 0};
    
    struct NODE
    {
        int x, y;
    }node[20], que[N*N];
    
    int col, row, limit, n_jewel, ans;
    int jewel[15], step[N][N];    //step记录广搜中到某个结点的步数
    int dis[20][20];
    char map[N][N];
    bool vis[20];
    
    bool no_overmap(int x, int y)
    {
        return (x >= 0 && x < col && y >= 0 && y < row);
    }
    
    int get_index(int x, int y)
    {
        if(map[x][y] == '@')
            return n_jewel + 1;
        else if(map[x][y] == '<')
            return n_jewel;
        else
            return map[x][y] - 'A';
    }
    
    void bfs(int root)   //breadth first search
    {
        for(int i = 0; i < col; ++i)
            for(int j = 0; j < row; ++j)
                step[i][j] = 0;
        int head = 0, tail = 0;
        que[++head].x = node[root].x;
        que[head].y = node[root].y;
        while(tail < head)
        {
            int x = que[++tail].x, y = que[tail].y;
            for(int i = 0; i < 4; ++i)
            {
                int nx = x + dir[0][i], ny = y + dir[1][i];
                if(no_overmap(nx, ny) && step[nx][ny] == 0 && map[nx][ny] != '*' &&
                   (nx != node[root].x || ny != node[root].y))
                {
                    step[nx][ny] = step[x][y] + 1;
                    if(map[nx][ny] != '.')
                    {
                        int to = get_index(nx, ny);
                        dis[root][to] = step[nx][ny];
                    }
                    que[++head].x = nx;
                    que[head].y = ny;
                }
            }
        }
    }
    
    void dfs(int root, int val, int time)
    {
        //记得判断当前点即root到终点的时间,否则超时,有的话也要900多毫秒才过
        if(time + dis[root][n_jewel] > limit)
            return;
        if(root == n_jewel)
        {
            ans = ans > val ? ans : val;
            return;
        }
        //由于最短路之前都求过了,dfs只要判断该点要或不要就可以了
        //则列举这些点的排列肯定有一种是答案,当前点可以要或不要
        for(int i = 0; i <= n_jewel; ++i)
        {
            if(vis[i] == false && time + dis[root][i] <= limit)
            {
                vis[i] = true;
                dfs(i, val + jewel[i], time + dis[root][i]);
                vis[i] = false;
            }
        }
    }
    
    int main()
    {
        freopen("in.txt", "r", stdin);
        int n_case;
        scanf("%d", &n_case);
        for(int ca = 1; ca <= n_case; ++ca)
        {
            printf("Case %d:\n", ca);
            scanf("%d%d%d%d", &row, &col, &limit, &n_jewel);
            for(int i = 0; i < n_jewel; ++i)
                scanf("%d", &jewel[i]);
            for(int i = 0; i < col; ++i)
            {
                getchar();
                for(int j = 0; j < row; ++j)
                {
                    map[i][j] = getchar();
                    if(map[i][j] == '@')
                    {
                        node[n_jewel + 1].x = i;
                        node[n_jewel + 1].y = j;
                        jewel[n_jewel + 1] = 0;
                    }
                    if(map[i][j] == '<')
                    {
                        node[n_jewel].x = i;
                        node[n_jewel].y = j;
                        jewel[n_jewel] = 0;
                    }
                    if(map[i][j] >= 'A' && map[i][j] <= 'J')
                    {
                        node[map[i][j] - 'A'].x = i;
                        node[map[i][j] - 'A'].y = j;
                    }
                }
            }
    
            for(int i = 0; i <= n_jewel + 1; ++i)
                for(int j = 0; j < i; ++j)
                    dis[i][j] = dis[j][i] = INF;
    
            bfs(n_jewel + 1);
            if(dis[n_jewel + 1][n_jewel] > limit)
            {
                printf("Impossible\n\n");
                continue;
            }
            
            for(int i = 0; i <= n_jewel; ++i)   //求i到各点的最短距离
                bfs(i);
    
            for(int i = 0; i <= n_jewel + 1; ++i)
                vis[i] = false;
                
            ans = 0;
            dfs(n_jewel + 1, 0, 0);
            printf("The best score is %d.\n", ans);
            if(ca != n_case)
                puts("");
        }
        return 0;
    }
  • 相关阅读:
    2018.8.20 Python之路---常用模块
    2018.8.16 正则表达式
    2018.8.15 python中的冒泡法排序
    2018.8.15 python 中的sorted()、filter()、map()函数
    2018.8.14 python中的内置函数(68个)
    2018.8.13 python中生成器和生成器表达式
    2018.8.10 python中的迭代器
    2018.8.9 python中的动态传参与命名空间
    python测试开发django(1)--开始Hello World!
    UPC-5120 Open-Pit Mining(最大权闭合子图)
  • 原文地址:https://www.cnblogs.com/gabo/p/2596890.html
Copyright © 2011-2022 走看看