HDU查找(3)

1044 Collect More Jewels

先bfs打表,再dfs找最大收益
注意:
1.bfs把每個點push進queue之前就檢查,否則ME
2.dfs最大值已經爲所有珠寶價值總和時直接返回,否則TE
3.注意對不能到達的點的處理,否則RE
測試樣例:

3
3 3 3 2
1 1
@*A
<*B
.*.

4.注意最後一行結尾沒有\n,否則PE

#pragma warning(disable:4996)
#include<cstdio>
#include<map>
#include<cmath>
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdlib>
#include<stack>
#include<queue>
#include<set>
using namespace std;

struct pos
{
    int line;
    int row;
};

struct treasure
{
    int value;
    pos p;
};

int num, result, sum;
int line, row, time, jewel;
//寶物位置,起點位置tr[0]終點位置tr[jewel+1]
treasure tr[15] = { {0,{0,0}} };

//地圖
char m[60][60];
bool flag[60][60];
//最短距離
int dist[15][15] = { 0 };
//所有節點是否被訪問過
bool node[15];

int chartoint(const char c)
{
    if (c == '@')return 0;
    if (c == '<')return jewel + 1;
    if (c >= 'A' && c <= 'J')return c - 'A' + 1;
}

void bfs()
{
    for (int i = 0; i <= jewel + 1; i++)
    {
        int unh = jewel + 1 - i;
        queue<pair<pos, int>> q;
        q.push({ tr[i].p,0 });
        memset(flag, 1, sizeof(flag)); flag[tr[i].p.line][tr[i].p.row] = 0;
        while (unh > 0 && !q.empty())
        {
            pair<pos, int> pa = q.front();
            pos cp = pa.first; int next = pa.second + 1; q.pop();
            int cl = cp.line, cr = cp.row;
            //up
            if (cl > 0 && m[cl - 1][cr] != '*' && flag[cl - 1][cr])
            {
                if (m[cl - 1][cr] != '.')
                {
                    int j = chartoint(m[cl - 1][cr]);
                    if (j > i)
                    {
                        dist[i][j] = next;
                        dist[j][i] = next;
                        unh--;
                    }
                }
                flag[cl - 1][cr] = 0;
                q.push({ {cl - 1,cr},next });
            }
            //left
            if (cr > 0 && m[cl][cr - 1] != '*' && flag[cl][cr - 1])
            {
                if (m[cl][cr - 1] != '.')
                {
                    int j = chartoint(m[cl][cr - 1]);
                    if (j > i)
                    {
                        dist[i][j] = next;
                        dist[j][i] = next;
                        unh--;
                    }
                }
                flag[cl][cr - 1] = 0;
                q.push({ {cl,cr - 1},next });
            }
            //down
            if (cl < line - 1 && m[cl + 1][cr] != '*' && flag[cl + 1][cr])
            {
                if (m[cl + 1][cr] != '.')
                {
                    int j = chartoint(m[cl + 1][cr]);
                    if (j > i)
                    {
                        dist[i][j] = next;
                        dist[j][i] = next;
                        unh--;
                    }
                }
                flag[cl + 1][cr] = 0;
                q.push({ {cl + 1,cr},next });
            }
            //right
            if (cr < row - 1 && m[cl][cr + 1] != '*' && flag[cl][cr + 1])
            {
                if (m[cl][cr + 1] != '.')
                {
                    int j = chartoint(m[cl][cr + 1]);
                    if (j > i)
                    {
                        dist[i][j] = next;
                        dist[j][i] = next;
                        unh--;
                    }
                }
                flag[cl][cr + 1] = 0;
                q.push({ {cl,cr + 1},next });
            }
        }
    }
}


//位置 已得分數 已用時間
void dfs(int c, int s, int t)
{    
    if (t > time || result == sum) 
        return;
    if (c == jewel + 1)
    {
        if (s > result)
            result = s;
        return;
    }
    node[c] = 1;
    for (int i = 0; i <= jewel + 1; i++)
    {
        if (node[i])continue;
        if (!dist[c][i])continue;
        dfs(i, s + tr[c].value, t + dist[c][i]);
    }
    node[c] = 0;
}
int main()
{
    scanf("%d", &num);
    for (int n = 0; n < num; n++)
    { 
        memset(dist, 0, sizeof(dist)); memset(node, 0, sizeof(node));
        result = -1; sum = 0;
        scanf("%d%d%d%d", &row, &line, &time, &jewel);
        for (int i = 1; i < jewel + 1; i++)
        {
            scanf("%d", &((tr + i)->value));
            sum += (tr + i)->value;
        }

        for (int i = 0; i < line; i++)
        {
            scanf("%s", m[i]); 
            for (int j = 0; j < row; j++)
            {
                switch (m[i][j])
                {
                case '@':tr[0] = { 0,{i,j} }; break;
                case '<':tr[jewel + 1] = { 0,{i,j} }; break;
                case '*':break;
                case '.':break;
                default:
                    tr[chartoint(m[i][j])].p.line = i;
                    tr[chartoint(m[i][j])].p.row = j;
                    break;
                }
            }
        }
        bfs();
        dfs(0,0,0);
        printf("Case %d:\n", n + 1);
        if(result==-1)printf("Impossible\n");
        else printf("The best score is %d.\n",result);
        if (n != num - 1)printf("\n");
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章