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");
}
}