fix: new faster heuristic used in solution

This commit is contained in:
2026-05-04 15:56:45 -03:00
parent 03a409f861
commit 6acc6e738d

View File

@@ -1,7 +1,7 @@
#include <bits/stdc++.h> #include <bits/stdc++.h>
#define endl '\n' #define endl '\n'
#define INF 0x3f #define INF 0x3f3f3f3f
using namespace std; using namespace std;
@@ -11,7 +11,6 @@ const int MAXN = 1e3 + 10;
int C, L, W; int C, L, W;
int Cr, Lr, Cs, Ls; int Cr, Lr, Cs, Ls;
int alagado[MAXN][MAXN];
const int COSTS[5][5] = { const int COSTS[5][5] = {
{7, 6, 5, 6, 7}, {7, 6, 5, 6, 7},
{6, 3, 2, 3, 6}, {6, 3, 2, 3, 6},
@@ -19,67 +18,47 @@ const int COSTS[5][5] = {
{6, 3, 2, 3, 6}, {6, 3, 2, 3, 6},
{7, 6, 5, 6, 7}, {7, 6, 5, 6, 7},
}; };
int vis[MAXN][MAXN]; bitset<MAXN> alagado[MAXN];
int g[MAXN][MAXN]; int g[MAXN][MAXN];
bool valid(int c, int l) { bool valid(int c, int l) {
return c > 0 && c <= C && l > 0 && l <= L && alagado[c][l] == 0; return c > 0 && c <= C && l > 0 && l <= L && alagado[c][l] == 0;
} }
int h(int c, int l) int h(int c, int l) {
{ int dx = abs(Cs - c);
return sqrt(abs(Cs - c)*abs(Cs - c) + abs(Ls - l)*abs(Ls - l)); int dy = abs(Ls - l);
}
bool reachable() int diag = min(dx, dy);
{ int straight = max(dx, dy) - diag;
queue<pii> q;
memset(vis, 0, sizeof(vis));
q.push({Cr, Lr}); return diag * 3 + straight * 2;
vis[Cr][Lr] = 1;
while (!q.empty())
{
auto [c, l] = q.front();
q.pop();
if (c == Cs && l == Ls) return true;
for (int i = -2; i <= 2; i++){
for (int j = -2; j <= 2; j++){
int nc = c + i, nl = l + j;
if (!valid(nc, nl) || vis[nc][nl]) continue;
vis[nc][nl] = 1;
q.push({nc, nl});
}
}
}
return false;
} }
void solve() void solve()
{ {
if (!reachable()) for (int i = 1; i <= C; i++){
{ for (int j = 1; j <= L; j++){
cout << "impossible" << endl; g[i][j] = INF;
return; }
} }
memset(vis, 0, sizeof(vis)); priority_queue<
memset(g, INF, sizeof(g)); pair<int, pii>,
priority_queue<pair<int, pii>> pq; vector<pair<int, pii>>,
greater<>
> pq;
g[Cr][Lr] = 0; g[Cr][Lr] = 0;
pq.push({-h(Cr, Lr), {Cr, Lr}}); pq.push({h(Cr, Lr), {Cr, Lr}});
while (!pq.empty()){ while (!pq.empty()){
auto [curCost, curCoords] = pq.top(); auto [curCost, curCoords] = pq.top();
pq.pop(); pq.pop();
auto [c, l] = curCoords; auto [c, l] = curCoords;
if (vis[c][l]) continue; if (curCost != g[c][l] + h(c,l)) continue;
vis[c][l] = 1;
if (c == Cs && l == Ls){ if (c == Cs && l == Ls){
cout << g[c][l] << endl; cout << g[c][l] << endl;
@@ -93,15 +72,16 @@ void solve()
int cost = COSTS[i+2][j+2]; int cost = COSTS[i+2][j+2];
int newG = g[c][l] + cost; int newG = g[c][l] + cost;
if (newG < g[nc][nl]){ if (newG < g[nc][nl]){
g[nc][nl] = newG; g[nc][nl] = newG;
int f = g[nc][nl] + h(nc, nl); pq.push({newG + h(nc, nl), {nc, nl}});
// insere custo negativo pois por padrao a priority queue é uma max heap
pq.push({-f, {nc, nl}});
} }
} }
} }
} }
cout << "impossible" << endl;
} }
int main() int main()
@@ -110,11 +90,13 @@ int main()
cin.tie(nullptr); cin.tie(nullptr);
while (cin >> C >> L, C && L){ while (cin >> C >> L, C && L){
cin >> Cr >> Lr; cin >> Cr >> Lr >> Cs >> Ls;
cin >> Cs >> Ls; for (int i = 1; i <= C; i++){
for (int j = 1; j <= L; j++){
alagado[i][j]=0;
}
}
cin >> W; cin >> W;
memset(alagado, 0, sizeof(alagado));
memset(vis, 0, sizeof(vis));
for (int i = 0; i < W; i++){ for (int i = 0; i < W; i++){
int C1, C2, L1, L2; int C1, C2, L1, L2;
cin >> C1 >> L1 >> C2 >> L2; cin >> C1 >> L1 >> C2 >> L2;