隨想錄 Day 74 Floyd / A*

隨想錄 Day 74 Floyd / A*

Bellman_ford 隊列優化

97. 小明逛公園

時間限制:1.000S 空間限制:256MB
題目描述
小明喜歡去公園散步,公園內布置了許多的景點,相互之間通過小路連接,小明希望在觀看景點的同時,能夠節省體力,走最短的路徑。

給定一個公園景點圖,圖中有 N 個景點(編號為 1 到 N),以及 M 條雙向道路連接著這些景點。每條道路上行走的距離都是已知的。

小明有 Q 個觀景計劃,每個計劃都有一個起點 start 和一個終點 end,表示他想從景點 start 前往景點 end。由于小明希望節省體力,他想知道每個觀景計劃中從起點到終點的最短路徑長度。 請你幫助小明計算出每個觀景計劃的最短路徑長度。

輸入描述
第一行包含兩個整數 N, M, 分別表示景點的數量和道路的數量。

接下來的 M 行,每行包含三個整數 u, v, w,表示景點 u 和景點 v 之間有一條長度為 w 的雙向道路。

接下里的一行包含一個整數 Q,表示觀景計劃的數量。

接下來的 Q 行,每行包含兩個整數 start, end,表示一個觀景計劃的起點和終點。

輸出描述
對于每個觀景計劃,輸出一行表示從起點到終點的最短路徑長度。如果兩個景點之間不存在路徑,則輸出 -1。
輸入示例
7 3
2 3 4
3 6 6
4 7 8
2
2 3
3 4
輸出示例
4
-1

提交

1、確定dp數組(dp table)以及下標的含義

這里我們用 grid數組來存圖,那就把dp數組命名為 grid。

grid[i][j][k] = m,表示 節點i 到 節點j 以[1…k] 集合為中間節點的最短距離為m。

# include <iostream>
# include <vector>
using namespace std;
int n, m;
int cnt;
int main() {cin>> n >>m;vector<vector<vector<int> > >  grid(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1, 10005))); for (int c = 0; c < m; c++) {int i, j , weight;cin>> i >>j >> weight;//cout << i << j << weight<<endl;grid[i][j][0] = weight;//注意這里是雙向圖grid[j][i][0] = weight;}for (int k = 1 ; k < n+1; k++) {for (int i = 1; i < n+1; i++) {for (int j = 1; j < n+1; j++){grid[i][j][k] = min(grid[i][j][k-1], grid[i][k][k-1] + grid[k][j][k-1]);}}}cin>> cnt;for (int i = 0; i < cnt; i++) {int start, end;cin>> start >> end;if (grid[start][end][n] > 10000){cout<< -1<< endl;} else {cout<< grid[start][end][n]<<endl;}}
}

A* method

原理介紹

題目:
126. 騎士的攻擊

時間限制:1.000S 空間限制:256MB
題目描述
在象棋中,馬和象的移動規則分別是“馬走日”和“象走田”。現給定騎士的起始坐標和目標坐標,要求根據騎士的移動規則,計算從起點到達目標點所需的最短步數。

棋盤大小 1000 x 1000(棋盤的 x 和 y 坐標均在 [1, 1000] 區間內,包含邊界)

輸入描述
第一行包含一個整數 n,表示測試用例的數量,1 <= n <= 100。

接下來的 n 行,每行包含四個整數 a1, a2, b1, b2,分別表示騎士的起始位置 (a1, a2) 和目標位置 (b1, b2)。

輸出描述
輸出共 n 行,每行輸出一個整數,表示騎士從起點到目標點的最短路徑長度。
輸入示例
6
5 2 5 4
1 1 2 2
1 1 8 8
1 1 8 7
2 1 3 3
4 6 4 6
輸出示例
2
4
6
5
1
0

提交

注意幾個細節

memst 再string.h包中

注意huristicbic 必須帶const 因為會被operator調用

A* 算法中沒走一步要* 5 (1^2 + 2^2)

pq.push(vector{x, y}); 注意這里的語法,容易寫成小括號,還不好查錯誤。

# include <iostream>
# include <vector>
# include <queue>
# include<string.h>
using namespace std;
int n;
int moves[1001][1001];
int dir[8][2]={-2,-1,-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2};
vector<int> start(2);
vector<int> target(2);
int Heuristic(const vector<int>& a, const vector<int>&b)  { // 歐拉距離return (a[1] - b[1]) * (a[1] - b[1]) + (a[0] - b[0]) * (a[0] - b[0]); // 統一不開根號,這樣可以提高精度
};
class cmp {public:bool operator() (const vector<int>& a, const vector<int>&b) {return moves[a[0]][a[1]] * 5 + Heuristic(a, target) > moves[b[0]][b[1]] * 5 + Heuristic(b, target);}
};
int shortestPath() {if (start == target) return 0;priority_queue<vector<int>, vector<vector<int> >, cmp > pq;//<vector<int> > q;//q.push(start);pq.push(start);//cout<< start[0] << "  " <<start[1] <<  endl;while(pq.size() != 0) {vector<int> now = pq.top();pq.pop();//cout << "now[0] " << now[0] << "  now[1] " <<now[1] <<"  move[now[0]][now[1]]  "<<moves[now[0]][now[1]] <<endl;for (int idx = 0; idx < 8; idx++) {int x = now[0] + dir[idx][0];int y = now[1] + dir[idx][1];//cout << "now[0] " << now[0] << "now[1] " <<now[1] <<"move[now[0]][now[1]]  "<<moves[now[0]][now[1]] <<endl;if (x == target[0] && y == target[1]) {return moves[now[0]][now[1]] + 1;}if (x >= 1 && x <= 1000 && y >= 1 && y <= 1000) {if (moves[x][y] == 0) {moves[x][y] = moves[now[0]][now[1]] + 1;pq.push(vector<int>{x, y});//cout << " x "<<x << " y "<< y <<" moves[x][y]" << moves[x][y]<<  endl;}}}}return -1;
};
int main() {cin>> n;for(int t = 0; t < n; t ++) {memset(moves,0,sizeof(moves));cin>> start[0] >> start[1]>> target[0] >> target[1];//cout << start[0] << " " << start[1]<< " " << target[0]<< " "<< target[1] << endl;cout << shortestPath()<<endl;}
}

A* 補充題

https://leetcode.cn/problems/shortest-path-in-binary-matrix/

1091. 二進制矩陣中的最短路徑

提示
中等
給你一個 n x n 的二進制矩陣 grid 中,返回矩陣中最短 暢通路徑 的長度。如果不存在這樣的路徑,返回 -1 。
二進制矩陣中的 暢通路徑 是一條從 左上角 單元格(即,(0, 0))到 右下角 單元格(即,(n - 1, n - 1))的路徑,該路徑同時滿足下述要求:
路徑途經的所有單元格的值都是 0 。
路徑中所有相鄰的單元格應當在 8 個方向之一 上連通(即,相鄰兩單元之間彼此不同且共享一條邊或者一個角)。
暢通路徑的長度 是該路徑途經的單元格總數。

Odinary bfs method

比較難看并不推薦

class Solution {
public:int dirs[8][2] = {{-1, 1}, {0, 1}, {1, 1},{-1, 0},         {1, 0},{-1, -1},{0, -1}, {1, -1}};int shortestPathBinaryMatrix(vector<vector<int>>& grid) {queue<pair<int,int> > que;int n = grid.size(); if (grid[0][0] == 1 || grid[n-1][n-1] == 1) return -1;if ( n == 1 ) return 1;que.emplace(0, 0);grid[0][0] = 1;int res = 1;while(!que.empty()) {res ++;int size = que.size();while (size--) {pair<int, int> temp = que.front();que.pop();for (int i = 0; i < 8; i++) {int x = temp.first + dirs[i][0];int y = temp.second + dirs[i][1];if (x == n-1 && y == n-1) return res;if (x >= 0 && x < n && y >= 0 && y < n) {if (grid[x][y] == 0) {que.emplace(x, y);grid[x][y] = 1;}}}}}return -1;}                                                                                                                                      
};
bfs with class method
class Solution {
public:int dirs[8][2] = {{-1, 1}, {0, 1}, {1, 1},{-1, 0},         {1, 0},{-1, -1}, {0, -1}, {1, -1}};class Node{public:int x, y, dis;Node(int a, int b, int c = 0) {x = a;y = b;dis = c;}};int shortestPathBinaryMatrix(vector<vector<int>>& grid) {queue<Node> que;int n = grid.size();if (grid[0][0] == 1 || grid[n - 1][n - 1] == 1) return -1;if (n == 1) return 1;Node start(0, 0, 1);que.push(start);grid[0][0] = 1;while (!que.empty()) {Node nod = que.front();que.pop();for (int i = 0; i < 8; i++) {int dx = nod.x + dirs[i][0];int dy = nod.y + dirs[i][1];int disten = nod.dis + 1;if (dx == n-1 && dy == n-1) {return disten;}if (dx < n && dx >= 0 && dy < n && dy >= 0 && grid[dx][dy] == 0) {grid[dx][dy] = 1;Node temp(dx, dy, disten);que.push(temp);}}}return -1;}
};
A* method
class Solution {
public:int dirs[8][2] = {{-1, 1}, {0, 1}, {1, 1},{-1, 0},         {1, 0},{-1, -1}, {0, -1}, {1, -1}};class Node{public:int x, y, dis, h;Node(int a, int b, int c) {x = a;y = b;dis = c;h = c + max(-a, -b);//針對切比雪夫距離的優化}friend bool operator <(Node f1, Node f2) {return f1.h > f2.h;}};   int shortestPathBinaryMatrix(vector<vector<int>>& grid) {int n = grid.size();priority_queue<Node> que;vector<vector<int> > minmap(n, vector<int>(n, 10000));
//記錄當前最小if (grid[0][0] == 1 || grid[n - 1][n - 1] == 1) return -1;if (n == 1) return 1;Node start(0, 0, 1);que.push(start);//grid[0][0] = 1;minmap[0][0] = start.h;while (!que.empty()) {Node nod = que.top();que.pop();for (int i = 0; i < 8; i++) {int dx = nod.x + dirs[i][0];int dy = nod.y + dirs[i][1];int disten = nod.dis + 1;if (dx == n-1 && dy == n-1) {return disten;}if (dx < n && dx >= 0 && dy < n && dy >= 0 && grid[dx][dy] == 0) {Node temp(dx, dy, disten); if( minmap[dx][dy] > temp.h){minmap[dx][dy] = temp.h;que.push(temp);}}}}return -1;}
};

sliding-puzzle

https://leetcode.cn/problems/sliding-puzzle/

在一個 2 x 3 的板上(board)有 5 塊磚瓦,用數字 1~5 來表示, 以及一塊空缺用 0 來表示。一次 移動 定義為選擇 0 與一個相鄰的數字(上下左右)進行交換.
最終當板 board 的結果是 [[1,2,3],[4,5,0]] 謎板被解開。
給出一個謎板的初始狀態 board ,返回最少可以通過多少次移動解開謎板,如果不能解開謎板,則返回 -1 。

BFS
class Solution {
public:string boardToString (vector<vector<int>> board) {string ret = "";for(int j = 0 ; j < 2; j++) {for (int i = 0; i < 3; i++) {ret += char(board[j][i] + '0');}}return ret;};vector<vector<int>> trans = {{1, 3}, {0, 2, 4}, {1, 5}, {0, 4}, {1, 3, 5}, {2, 4}};vector<string> nextStates(string now) {vector<string> ret;int loc = now.find('0');for (int exchangeLoc : trans[loc]) {swap(now[loc], now[exchangeLoc]);ret.push_back(now);swap(now[loc], now[exchangeLoc]);}return ret;};int slidingPuzzle(vector<vector<int>>& board) {string start = boardToString(board);if (start == "123450") return 0;unordered_set<string> reached;reached.insert(start);queue<pair<string, int> >q;q.emplace(start, 0);while(!q.empty()) {string now = q.front().first;int step = q.front().second;q.pop();step ++;for (string nxt : nextStates(now)) {if (nxt == "123450") return step;if (!reached.count(nxt)) {q.emplace(nxt, step);reached.insert(nxt);}}}return -1;}
};
A* methods
class Solution {
public:string boardToString (vector<vector<int>> board) {string ret = "";for(int j = 0 ; j < 2; j++) {for (int i = 0; i < 3; i++) {ret += char(board[j][i] + '0');}}return ret;};vector<vector<int> > trans = {{1, 3}, {0, 2, 4}, {1, 5}, {0, 4}, {1, 3, 5}, {2, 4}};class States {public:vector<vector<int> > Manhatten = {{0, 1, 2, 1, 2, 3},{1, 0, 1, 2, 1, 2},{2, 1, 0, 3, 2, 1},{1, 2, 3, 0, 1, 2},{2, 1, 2, 1, 0, 1},{3, 2, 1, 2, 1, 0}};string state;int step;int h;int f;        States(string st, int sp) {state = st;step = sp;h = get_h(st);f = h + sp;};int get_h(string st) {int ret = 0;for (int i = 0; i <6; i++) {if (st[i] != '0') {ret += Manhatten[i][st[i] - '1'];}}return ret;};friend bool operator < (const States &a, const States &b) {return a.f > b.f;};};vector<string> nextStates(string now) {vector<string> ret;int loc = now.find('0');for (int exchangeLoc : trans[loc]) {swap(now[loc], now[exchangeLoc]);ret.push_back(now);swap(now[loc], now[exchangeLoc]);}return ret;};int slidingPuzzle(vector<vector<int>>& board) {string start = boardToString(board);if (start == "123450") return 0;States init(start, 0);unordered_map<string, int> min_reached;min_reached[init.state] = init.f;priority_queue<States>q;q.push(init);while(!q.empty()) {States current = q.top();q.pop();string now = current.state;int step = current.step;step ++;for (string nxt : nextStates(now)) {if (nxt == "123450") return step;States next(nxt, step);if (!min_reached.count(nxt) || min_reached[nxt] > next.f ) {min_reached[nxt] = next.f;q.push(next);}}}return -1;}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/38981.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/38981.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/38981.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

小和問題和逆序對問題

小和問題和逆序對問題 小和問題&#xff0c; 在一個數組中&#xff0c;每一個數左邊的數中比當前數小的數累加起來&#xff0c;叫做這個數組的小和&#xff0c;求一個數組的小和 直接遍歷&#xff1a; int littleSum1(int* arr, int L, int R) {int temp 0;for (int i L; …

Spring底層原理之bean的加載方式四 @import 注解

bean的加載方式四 import 第四種bean的導入方式 是import導入的方式 在配置類上面加上注解就行 package com.bigdata1421.config;import com.bigdata1421.bean.Dog; import org.springframework.context.annotation.Import;Import(Dog.class) public class SpringConfig4 {…

CesiumJS【Basic】- #041 繪制紋理線(Entity方式)- 需要自定義著色器

文章目錄 繪制紋理線(Entity方式)- 需要自定義著色器1 目標2 代碼2.1 main.ts3 資源文件繪制紋理線(Entity方式)- 需要自定義著色器 1 目標 使用Entity方式繪制紋理線 2 代碼 2.1 main.ts import * as Cesium from cesium;const viewer = new Cesium.Viewer

Java并發編程:最佳實踐與性能優化

Java并發編程&#xff1a;最佳實踐與性能優化 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 介紹并發編程 在當今軟件開發中&#xff0c;多核處理器和分布式…

K8S學習教程(一):使用PetaExpress云服務器安裝Minikube 集群題

什么是Minikube Minikube是一款工具&#xff0c;主要用于在本地運行 Kubernetes 集群。Kubernetes 開源的平臺&#xff0c;用于自動化容器化應用的部署、擴展和管理&#xff0c;而Minikube 使得開發人員能夠在本地機器上輕松創建一個單節點的 Kubernetes 集群&#xff0c;從而…

【高級篇】第6章 Elasticsearch 高級查詢與搜索優化

在Elasticsearch的深入應用之旅中,掌握高級查詢技巧與優化搜索性能是提升數據處理效率的關鍵。本章將帶你深入探索Elasticsearch的高級查詢特性,揭示搜索性能優化的奧秘,以及如何利用高亮與建議API增強用戶體驗。 6.1 復雜查詢 6.1.1 Nested查詢 Nested基本概念與用法: …

IT設備監控模板:支持多種監控工具和平臺的集成和整合

IT設備監控模板管理在支持多種監控工具和平臺方面發揮著關鍵作用&#xff0c;它通過提供統一的配置和管理界面&#xff0c;使運維人員能夠靈活地適應和整合不同的監控工具和平臺。以下是IT設備監控模板管理如何支持多種監控工具和平臺的具體方式&#xff1a; 一、抽象化和標準…

如何使用AI學習一門編程語言?

無論你是軟件開發新手還是擁有幾十年的豐富經驗&#xff0c;總是需要學習新知識。TIOBE Index追蹤50種最受歡迎的編程語言&#xff0c;許多生態系統為職業發展和橫向轉型提供了機會。鑒于現有技術具有的廣度&#xff0c;抽空學習一項新技能并有效運用技能可能困難重重。 最近我…

ARCGIS python 裁剪柵格函數 arcpy.management.Clip

ARCGIS python 裁剪柵格函數 arcpy.management.Clip 1 功能 裁剪掉柵格數據集、鑲嵌數據集或圖像服務圖層的一部分。 2 使用情況 基于模板范圍提取部分柵格數據集&#xff0c;輸出與模板范圍相交的所有像素使用以 x 和 y 坐標的最小值和最大值確定的包絡矩形或使用輸出范圍文…

MATLAB-振動問題:單自由度阻尼振動系統受迫振動

一、基本理論 二、MATLAB實現 單自由度阻尼振動系統受迫振動&#xff0c;MATLAB代碼如下&#xff1a; clear; clc; close allA 1; psi 0; F0 10; D 20; Rm 0.5; M 1; omega 2; delta Rm / (2*M); omega0 sqrt(D / M); Omega sqrt(omega0^2 - delta^2); Zm Rm i *…

多線程的三種創建方式

繼承Thread類的方式進行實現 public class MyThread extends Thread{ Override public void run(){//多線程具體業務邏輯} }在main方法里面創建子類對象&#xff0c;開啟線程 public static void main(String[] args) {MyThread t1 new MyThread(); MyThread t2 new MyThrea…

LLM大模型工程師面試經驗寶典--基礎版(2024.7月最新)

1.簡單介紹一下大模型【LLMs】&#xff1f; 大模型&#xff1a;一般指1億以上參數的模型&#xff0c;但是這個標準一直在升級&#xff0c;目前萬億參數以上的模型也有了。大語言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;是針對語言的大模型。 2.目前主…

基于布雷格曼偏差校正技術的全變分一維時間序列信號降噪方法(MATLAB R2018A)

信號降噪是信號處理的重要步驟之一&#xff0c;目的是提高所獲得信號數據的質量&#xff0c;以達到更高的定性和定量分析精度。信號降噪能提升信號處理其他環節的性能和人們對信息識別的準確率&#xff0c;給信號處理工作提供更可靠的保證。信號降噪的難點是降低噪聲的同時也會…

69. x 的平方根(簡單)

69. x 的平方根 1. 題目描述2.詳細題解3.代碼實現3.1 Python方法一&#xff1a;逐個遍歷方法二&#xff1a;二分查找 3.2 Java 1. 題目描述 題目中轉&#xff1a;69. x 的平方根 2.詳細題解 不能使用系統內置的函數&#xff0c;尋找某個數&#xff08;假定為x&#xff09;的…

網絡請求的高效處理:C++ libmicrohttpd庫詳解

一、libmicrohttpd簡介 libmicrohttpd是一個小型的C語言庫&#xff0c;用于創建HTTP服務器和客戶端。它提供了HTTP 1.1協議的完整實現&#xff0c;包括持久連接、管道化請求、虛擬主機等特性。libmicrohttpd的特點是&#xff1a; 輕量級&#xff1a;易于集成到C或C項目中。跨…

微信好友不小心拉黑了?這樣操作,友誼的小船不會翻

在數字化時代&#xff0c;微信已成為我們社交生活的核心&#xff0c;它不僅連接著親朋好友&#xff0c;更承載著我們的情感與回憶。 然而&#xff0c;情緒波動時&#xff0c;我們可能會一時沖動&#xff0c;將某些好友誤送入黑名單。但別擔心&#xff0c;今天&#xff0c;就讓…

IMU在手語識別中的應用

近期&#xff0c;一款由美國和中國科研團隊聯合研發的新型的穿戴設備——SignRing&#xff0c;以其獨特的IMU&#xff08;慣性測量單元&#xff09;技術&#xff0c;為聾啞人士的手語識別帶來了革命性的突破。SignRing不僅極大地擴展了手語識別的詞匯量&#xff0c;更提高了識別…

二維數組-----螺旋性矩陣輸出

題目有點難&#xff0c;ok其實是很難。。。 觀察樣例輸出&#xff0c;不難發現&#xff0c;螺旋數組中元素的遞增軌跡為&#xff1a;右右右、下下下、左左左、上上上 簡明為&#xff1a;右、下、左、上。可以設開始遞增的元素1的位置為&#xff08;x&#xff0c;y)&#xff0c…

由跨域引發一些思考

由跨域引發一些思考 前言什么是跨域&#xff1f;為什么會產生跨域&#xff1f;跨域場景示例&#xff1a;跨域常見的解決方法&#xff1a;JSONP&#xff08;JSON with Padding&#xff09;CORS&#xff08;Cross-Origin Resource Sharing&#xff09;document.domain iframeloc…

AutoHotKey自動熱鍵(二)中文版幫助手冊下載和自定義一般鍵盤快捷鍵

所有的操作其實在開發者手冊中已經交待完了,所以我們要使用中文的手冊來進行使用 autohotkey1.1.15中文手冊下載 好了,為什么有了中文手冊,這里還要進行一些具體的介紹呢,就是為了讓大家少踩坑,能夠快速形成生產力 這里先講一下自定義快捷鍵WIN鍵和ALT鍵和CTRL鍵和SHIFT鍵的組…