1. 程式人生 > >九度OJ 1091棋盤遊戲

九度OJ 1091棋盤遊戲

題目描述:

有一個6*6的棋盤,每個棋盤上都有一個數值,現在又一個起始位置和終止位置,請找出一個從起始位置到終止位置代價最小的路徑:
1、只能沿上下左右四個方向移動
2、總代價是沒走一步的代價之和
3、每步(從a,b到c,d)的代價是c,d上的值與其在a,b上的狀態的乘積
4、初始狀態為1
每走一步,狀態按如下公式變化:(走這步的代價%4)+1。

輸入:

第一行有一個正整數n,表示有n組資料。
每組資料一開始為6*6的矩陣,矩陣的值為大於等於1小於等於10的值,然後四個整數表示起始座標和終止座標。

輸出:

輸出最小代價。

樣例輸入:

1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
0 0 5 5

樣例輸出:

23

注意,這道題不能採用BFS,雖然求的是最優解,可是若採用BFS不一定能保證得到的是最小min_cost,本質是因為問題求得的解並不是隨步數的增大而一定增大的,它還考慮了節點的value,state。很明顯這不是線性遞增的,因此不能用BFS。

這道題本質上還是考察圖的遍歷,這次用的DFS。

在DFS開始的時候需要剪枝(去掉一些情況,減小時間複雜度),因為這裡要求的是最小的代價,當在找路的時候發現當前的代價已經大於min_cost的時候,就不需要考慮從當前點往下的路徑,因為應經不可能是最優的路。

因為每次執行一個動作,都需要用到前一個的狀態和目前的代價和,所以在DFS的引數中要有這兩個變數。

為了避免在找路的過程中出現死迴圈,需要設定visit[][]變數,防止在找其中某一條路徑的時候往回走,也就是說在每次執行到某個點的時候,將visit的值設為1;為了防止訪問過的點,在尋找第二條新路徑的時候還可以被訪問,我們需要將visit的值在每次DFS之後,重新初始化為0,這點我開始的時候沒有考慮到。

但是不知道為什麼顯示Wrong Answer。

#include<string>
#include<iostream>
#include<stdio.h>
using namespace std; int map[6][6]; int start_x,start_y,end_x,end_y; bool mark[6][6]; int move[4][2] = {{0,1},{0,-1},{-1,0},{1,0}}; //對應向右,左 int min_cost=10000; void DFS(int x,int y,int cost,int state){ if(cost< min_cost){ if(x==end_x && y==end_y){ min_cost=cost; return ; } int i; for(i=0;i<4;i++){ int nx=x+move[i][0]; int ny=y+move[i][1]; if(nx<0 || nx>=6 || ny<0 || ny>=6) continue; if(mark[nx][ny]==false){ int tmp=state*map[nx][ny]; int nstate=(tmp%4)+1; int ncost=cost+tmp; mark[nx][ny]=true; DFS(nx,ny,ncost,nstate); mark[nx][ny]=false; } } } } int main(){ int n; cin>>n; while(n--){ int i,j; for(i=0;i<6;i++) for(j=0;j<6;j++){ scanf("%d",&map[i][j]); mark[i][j]=false; //未被標記 } cin>>start_x>>start_y>>end_x>>end_y; DFS(start_x,start_y,0,1); printf("%d\n",min_cost); } return 0; }

相關推薦

OJ 1091棋盤遊戲

題目描述: 有一個6*6的棋盤,每個棋盤上都有一個數值,現在又一個起始位置和終止位置,請找出一個從起始位置到終止位置代價最小的路徑: 1、只能沿上下左右四個方向移動 2、總代價是沒走一步的代價之和 3、每步(從a,b到c,d)的代

OJ 1091 棋盤遊戲

題目描述:     有一個6*6的棋盤,每個棋盤上都有一個數值,現在又一個起始位置和終止位置,請找出一個從起始位置到終止位置代價最小的路徑:     1、只能沿上下左右四個方向移動     2、總代價是沒走一步的代價之和     3、每步(從a,b到c,d)的代價是c,d

DFS和BFS 解棋盤遊戲OJ 1091

DFS利用遞迴,不必使用多餘的資料結構,實現簡單。但要注意剪枝。 BFS藉助佇列,往往在求最優解時使用。總是能找到最優解,某些情況下也要剪枝。 這兩種方法根據具體問題來使用。 以此題為例,DFS和BFS都可求解。 由於是求最優解,用BFS更為直接。 由於此題的不確定性,必須要

OJ 題目1204:農夫、羊、菜和狼的故事

pla pan wol 題目 r+ ear play struct tab 思路:廣度 優先 記錄路徑長度 但是題目的意思好像是要記錄具體路徑 下次再搞吧 題目描述: 有一個農夫帶一只羊、一筐菜和一只狼過河.果沒有農夫看管,則狼要吃羊,羊要吃菜.但是船很小,只

OJ-題目1009:二叉搜索樹

提交 二叉排序樹 軟件 amp cpp creat .com xheditor ear 題目1009:二叉搜索樹 從如今開始打算重新啟動刷題征程。程序猿的人生不須要解釋! 這次撇開poj hoj等難度較大的oj系統,從九度入手(已經非常長時間沒寫過代碼

&lt; OJ&gt;題目1012:暢通project

數組下標 find cout set href col 設置 data [] 題目描寫敘述: 某省調查城鎮交通狀況,得到現有城鎮道路統計表。表中列出了每條道路直接連通的城鎮。省政府“暢通project”的目標是使全省不論什麽兩個城鎮間都能夠實現

oj---oj--1078---二叉樹重建

pre urn pac uil pri () esp 通過 str 通過兩種遍歷結果重建,必須有中序遍歷(找到根的位置)。 #include<cstdio> #include<cstring> #include<string> #i

oj---oj---1015

class sca pri main esp int nbsp color pre #include<cstdio> #include<algorithm> #include<cstring> using namespace

oj---oj---1043----day of week

sunday clu %d process put else ril nbsp pro #include<cstdio> #include<cstring> int isleap(int n){ if((n%100!=0&&

oj---oj---1070----今年的第幾天

struct else print scan mon urn roc style *** 通過與原點的差值來計算第幾天(要+1). #include<cstdio> int isleap(int n){ if((n%100!=0&&

oj----oj----1186---第幾天---輸出日期

int 大於 spa return log ... include void ext 利用日期類的nextday(); 或者先加一個月的天數,然後判斷是否大於給定天數,然後再加一個月的天數,在判斷.... #include<cstdio> int isl

oj--oj--1018

mem pan main return clas != bre 九度oj size 簡單hash #include<cstdio> #include<cstring> int grade[101]; int main(){ int n;

oj---oj---1052

can class res return cst ring code printf log #include<cstdio> #include<cstring> int buf[205]; int main(){ int n;

oj---oj---1432

span out color code can tdi bool pan cnblogs 先排版,再輸出。 先定位中心坐標,然後定位左上角坐標,然後開始排版,四邊同步。左上角起始為(1,1) . #include<cstdio> char output[8

oj---oj---1433

else blog sin == con for ++ clu return #include<cstdio> #include<algorithm> using namespace std; const double eps=1e-8;

oj---oj---1434

printf %d truct sin col break pre nbsp bre #include<cstdio> #include<algorithm> using namespace std; struct Program{

oj--oj---1435

比較 col esp == int -1 n) style tdi 貪心,每次選擇濃度最低的。 註意浮點數比較的問題。 AC如下: #include<cstdio> #include<algorithm> #include<cmath&g

oj---oj---1153

emp () can top tac != name names main #include<cstdio> #include<stack> using namespace std; char str[110]; char res[110]

oj---oj---1107

names cst stack reat priority pac tac turn prior #include<cstdio> #include<iostream> #include<queue> #include<m

oj---oj---1201

fine 可讀性 設定 實現 程序 指向 null 我們 附加 0是NULL的一個實現,但NULL不是0。 指針的數值是其所指向的內存的地址。很多時候我們需要標明“這個指針當前為無效指針,它不指向任何可以使用的內存空間”,因為不能在指針外附加一個標誌位,所以就需要設定一