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;

}

 

你可能感兴趣的:(more)