YTU 3166 共享單車 DFS 記憶化搜索

問題 D: 共享單車

題目描述

共享單車走進煙臺,小明決定嘗試。小明啟動共享單車 App,輕松地找到附近的單車。那么問題來了,到最近的那輛單車,小明大約要走多少米呢?

現在簡化問題。將地圖設定成一個由 100×100 米的像素塊組成的二維平面區域。如果一個方塊內有單車,則像素塊顯示為字符 x;如果此方塊內是可以通行的路,則顯示為 .;再如果方塊是建筑物,則顯示為 *,建筑物不能通行。

小明在地圖上的位置顯示為 o,可以朝,“上”、“下”、“左”,“右”,“左上”,“左下”,“右上”,“右下”八個方向走。下圖所示為一個小明站在像素方塊 O,如果小明向右走到 X,則走 100 米;如果向右上走,則走 141 米(不需要開方)。

假設小明和單車都在方塊的中央。現在給出 T 幅根據以上規則建立的地圖,地圖行數和列數分別為 n 和 m,請分別估算小明要走多少米才能到最近的單車?

給出的地圖中至少有一輛單車,如果最終無法到達單車的位置,輸出 -1

輸入

第 1 行 T,表示下面有 T 組測試數據

對于每組測試數據

第 1?行 n 和 m,表示地圖的大小;

第 2 行開始,給出具體的地圖?。

輸出

T?行數據

每行 1?個整數,表示問題的解

輸入輸出樣例

樣例輸入 #1

復制

2
3 8
.....x..
.o...x..
........
8 10
.***......
.***......
.***..x...
..........
.....*****
..o..*****
.......x..
...*******
樣例輸出 #1

復制

400
523

提示

如果計算中出現小數,那么直接舍棄。最后的輸出的結果為整型。

記憶化搜索:

記憶化搜索是深搜的一種剪枝策略,記憶化搜索就是讓程序記住一些東西,然后在需要時可以快速調用,用什么來存貯數據?用數組

記憶化搜索是在搜索過程中,會有很多重復計算,如果我們能記錄一些狀態的答案,就可以減少復搜索量
?

記憶化搜索的核心實現:

1.首先,要通過一個數組記錄已經存儲下的搜索結果

2.狀態表示,由于是要用數組實現,所以狀態最好可以用數字表示,

3.在每一狀態搜索的開始,高效的使用數組查看這個狀態是否出現過,如果已經做過,直接調用答案,如果沒有,則按正常方法搜索

以斐波那契數列為例,記憶化代碼入下:

int memorize[N]; //保存結果
int fib(int n)
{if(n==1 || n==2) return 1; if(memorize[n]!=0) return memorize[n];  //直接返回保存的結果,不再遞歸memorize[n]=fib(n-1)+fib(n-2);          //遞歸計算結果,并記憶return memorize[n];
}

在這段代碼中,一個斐波那契數列只計算一次,所以總時間復雜度為O(n)
?

我們先用一道熟悉的題目引入記憶化搜索:
https://blog.csdn.net/2302_79545206/article/details/137286031?spm=1001.2014.3001.5501

思路:?

從o點出發,要尋找距離最近的共享單車,因為要求最近距離,我們初始化距離為無窮遠,用一個d數組來記錄個點距離o點的最短距離,并初始化為無窮大,每次進行下一次dfs之前,首先先進行判斷走這一步是否可以使到達我們要到達的點的距離更近,這樣進入dfs便可以直接更新,找到一個共享單車,做比較尋找最優解。

代碼實現:?

#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>using namespace std;typedef long long ll;typedef pair<int,int> PII;const int INF=0x3f3f3f3f;
const int N=105;char g[N][N];
bool vis[N][N];int ans=INF;
bool f=false;
int n,m;int d[N][N];///記憶化搜索int xx,yy;void dfs(int x,int y,int dis)///(x,y)記錄點的位置,dis記錄該點距離o點的距離
{if(x<1 || x>n || y<1 || y>m) return;///判斷點是否越界d[x][y]=dis; /// 更新最短距離,因為已經做過判斷了,所以這里直接更新if(g[x][y]=='x')///找到共享單車{f=true;ans=min(ans,d[x][y]);///選擇距離更近的最優解return;}else{if(!vis[x+1][y] && dis+100<d[x+1][y] && g[x+1][y]!='*') ///右{vis[x+1][y]=true;dfs(x+1,y,dis+100);vis[x+1][y]=false;}if(!vis[x-1][y] && dis+100<d[x-1][y] && g[x-1][y]!='*') ///左{vis[x-1][y]=true;dfs(x-1,y,dis+100);vis[x-1][y]=false;}if(!vis[x][y+1] && dis+100<d[x][y+1] && g[x][y+1]!='*') ///上{vis[x][y+1]=true;dfs(x,y+1,dis+100);vis[x][y+1]=false;}if(!vis[x][y-1] && dis+100<d[x][y-1] && g[x][y-1]!='*') ///下{vis[x][y-1]=true;dfs(x,y-1,dis+100);vis[x][y-1]=false;}if(!vis[x-1][y-1] && dis+141<d[x-1][y-1] && g[x-1][y-1]!='*') ///左下{vis[x-1][y-1]=true;dfs(x-1,y-1,dis+141);vis[x-1][y-1]=false;}if(!vis[x+1][y+1] && dis+141<d[x+1][y+1] && g[x+1][y+1]!='*') ///右上{vis[x+1][y+1]=true;dfs(x+1,y+1,dis+141);vis[x+1][y+1]=false;}if(!vis[x-1][y+1] && dis+141<d[x-1][y+1] && g[x-1][y+1]!='*') ///左上{vis[x-1][y+1]=true;dfs(x-1,y+1,dis+141);vis[x-1][y+1]=false;}if(!vis[x+1][y-1] && dis+141<d[x+1][y-1] && g[x+1][y-1]!='*') ///右下{vis[x+1][y-1]=true;dfs(x+1,y-1,dis+141);vis[x+1][y-1]=false;}}return;
}void solve()
{cin>>n>>m;ans=INF;///初始化memset(d,0x3f,sizeof(d)); ///初始化圖上每個點到小明的距離為無窮遠f=false;///不能到達共享單車memset(vis,false,sizeof(vis));///因為是多組數據輸入輸出因此要初始化for(int i=1; i<=n; i++)///圖的存儲{for(int j=1; j<=m; j++){cin>>g[i][j];if(g[i][j]=='o'){xx=i;yy=j;}}}dfs(xx,yy,0);///從o點開始搜索if(f==false) printf("-1\n");else cout<<ans<<endl;}int main()
{int T;cin>>T;while(T--){solve();}return 0;
}

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

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

相關文章

【UE】仿原神實現無限道路延伸的開場效果

目錄 效果 步驟 一、無限生成磚塊 二、制作門 三、停止移動并生成門 四、進入門 效果 步驟 一、無限生成磚塊 1. 新建一個Basic關卡&#xff0c;再新建一個Pawn類&#xff0c;這里命名為“BP_MyPawn” 打開“BP_MyPawn”&#xff0c;添加一個膠囊體碰撞組件和一個攝像…

工器具管理(基于若依)

文章目錄 前言一、工器具管理項目總覽 二、入庫功能1. 前端1.1 界面展示1.2 具體操作實現1.3 js文件 2. 后端2.1 工器具信息回顯2.2 工器具入庫 三、領用功能1. 前端1.1 界面展示1.2 具體實現操作1.3 js文件 2. 后端2.1 工器具信息回顯2.2 工器具領用 遇到的問題1. 同一頁面展示…

pat乙1033-舊鍵盤打字

1測試點2&#xff1a; 輸入的字符串如果為空&#xff0c;要用getline(cin,s)&#xff0c;而不是cin>>s&#xff0c;否則程序做不了 2題目說的如果上鍵壞了那大寫字母打印不了&#xff0c;不是大寫轉小寫打印啦&#xff0c;認真讀題 3兩個for循環長這樣&#xff0c;break…

基于springboot+vue的自習室管理和預約系統(全套)

一、系統架構 前端&#xff1a;vue | element-ui | html 后端&#xff1a;springboot | mybatis-plus 環境&#xff1a;jdk1.8 | mysql | maven | nodejs 二、代碼及數據庫 三、功能介紹 01. web端-首頁1 02. web端-首頁2 03. web端-注冊 04. web端-登錄 05. w…

牛客Linux高并發服務器開發學習第六天

目錄相關函數 學習進度&#xff1a; Linux系統編程入門 06&#xff1a;59&#xff1a;42

Apollo9.0 Control模塊算法源碼學習

參考資料 Apollo控制算法_嗶哩嗶哩_bilibili

Python自動化測試 | 如何使用Robot Framework進行自動化測試?

你還在手動測試&#xff1f;不妨了解一下更高效、準確且簡單的測試方法——使用Python的Robot Framework進行自動化測試。 什么是Robot Framework&#xff1f; Robot Framework是一款開源的Python自動化測試框架&#xff0c;它基于關鍵字驅動的思想&#xff0c;具有易讀、易擴…

每日一題 城市群的數量

題目解析 城市群數量_牛客題霸_牛客網 當解決這個問題時&#xff0c;首先需要理解題目要求。題目中給出了一個城市之間的鄰接矩陣&#xff0c;矩陣中的元素表示城市之間是否直接相連。如果兩個城市直接相連&#xff0c;或者通過其他城市間接相連&#xff0c;它們就屬于同一個城…

算法學習筆記(匈牙利算法)

匈牙利算法可以求解二分圖的最大匹配問題&#xff08;二分圖&#xff1a;如果無向圖 G ( V , E ) G (V, E) G(V,E)的所有點可以分為兩個集合 V 1 、 V 2 V_1、V_2 V1?、V2?&#xff0c;所有的邊都在 V 1 V_1 V1?和 V 2 V_2 V2?之間&#xff0c;而 V 1 V_1 V1?或 V 2 V_2…

深入理解Python的類,實例和type函數

問題起源&#xff1a; class t():pass s1 t() s2 type("Student2",(),{}) isinstance(s1, type), isinstance(s2, type)為什么第一個是false&#xff0c;第二個是true呢 根因定位&#xff1a; 在Python中&#xff0c;一切皆對象&#xff0c;類是對象&#xff0c…

nacos在沒有指定數據源的情況下默認使用什么數據庫?

在沒有特別指定數據源的情況下&#xff0c;Nacos 默認使用內嵌的數據庫 Derby 來存儲其數據。Derby 是一個輕量級的、基于 Java 的數據庫管理系統&#xff0c;適合于開發和測試環境&#xff0c;因為它簡單易部署且無需額外的數據庫服務器。然而&#xff0c;對于生產環境&#x…

使用ORM快速獲取業務對象列表

通常在實際開發中&#xff0c;業務對象的信息是需要來自多個數據表的。 我們如果想要獲取這個業務對象&#xff0c;就要先查詢數據表&#xff0c;再把查詢到的數據依次循環&#xff0c;組合轉換封裝成業務要使用的對象類型列表。 如果使用了ORM&#xff0c;那么這個過程就可以簡…

Stability AI 推出 Stable Artisan,終于可以在Discord上使用Stable Diffusion了!

Stable Diffusion 社區最常見的要求之一是能夠直接在 Discord 上使用他們的模型。近期&#xff0c;Stability AI 推出 Stable Artisan&#xff0c;這個需求終于被實現了。 Stable Artisan 支持在 Discord 上生成媒體&#xff0c;由 Stability AI 的尖端圖像和視頻模型 Stable D…

基于Springboot的實習生管理系統(有報告)。Javaee項目,springboot項目。

演示視頻&#xff1a; 基于Springboot的實習生管理系統&#xff08;有報告&#xff09;。Javaee項目&#xff0c;springboot項目。 項目介紹&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三層體系結構&a…

mysql group by使用方法實例講解

MySQL中GROUP BY語句用于對某個或某些字段查詢分組&#xff0c;并返回重復記錄的第一條&#xff0c;本文章通過實例向大家介紹mysql group by使用方法和需要注意的地方&#xff0c;感興趣的朋友可以參考一下。 現在有這樣一個數據表book idfirst_namelast_namecityage1JasonM…

知乎知+廣告推廣該如何做?怎么收費?

知乎作為一個匯聚高質量用戶群體的知識分享平臺&#xff0c;成為了眾多品牌和產品推廣的優選之地。特別是知乎的“知”廣告推廣服務&#xff0c;以其精準定向、內容原生的特點&#xff0c;深受廣告主青睞。 一、知乎知廣告推廣基礎 1. 什么是知乎知&#xff1f; 知是知乎官方…

C++初階學習第七彈——探索STL奧秘(二)——string的模擬實現

標準庫中的string&#xff1a;C初階學習第六彈——string&#xff08;1&#xff09;——標準庫中的string類-CSDN博客 前言&#xff1a; 在前面我們已經學習了如何使用標準庫中的string類&#xff0c;但作為一個合格的程序員&#xff0c;我們不僅要會用&#xff0c;還要知道如…

C++類和對象下——實現日期類

前言 在學習了類和對象的六大成員函數后&#xff0c;為了鞏固我們學習的知識可以手寫一個日期類來幫助我們理解類和對象&#xff0c;加深對于其的了解。 默認函數 構造函數 既然是寫類和對象&#xff0c;我們首先就要定義一個類&#xff0c;然后根據實際需要來加入類的數據與函…

AI編程工具為什么選github copilot?

Github Copilot 是一個奇跡 它的競爭對手&#xff08;Amazon, Google, Meta, 騰訊&#xff09;都是免費的&#xff0c;但每月10-20美元的Github Copilot市場占有率最高。 1、2021年6月上線&#xff0c;比ChatGPT早近一年半 2、GitHub統計&#xff1a; 88%的用戶獲得效率提升平…

element ui的確認提示框文字樣式修改

修改確認提示框文字樣式修改&#xff0c;使用message屬性修改&#xff1a; 例&#xff1a; js代碼&#xff1a; this.$msgbox({title: 確定要刪除嗎?,message: this.$createElement(p, null, [this.$createElement(span, { style: color: red }, 該素材一旦刪除&#xff0c;…