這是乙個關於二維格仔狀迷宮的題目。迷宮的大小為n*m,左上角格仔座標為(1,1)、右上角格仔座標為(1,m)、左下角格仔座標為(n,1)、右下角格仔座標為(n,m)。每一格都用-1到10
9之間的整數表示,意義分別為:-1為牆壁,0為走道,而1到10
9之間的正整數代表特殊的走道。
蜥蜴最初位於迷宮的座標(1,1)的格仔,每一步蜥蜴只能往上、下、左、右、左上、右上、左下、右下八個方向之一前進一格,並且,他也不能走出迷宮邊界。蜥蜴的目的地是走到迷宮的右下角格仔,也就是座標位置(n,m)。我們想要動一些手腳,使得蜥蜴沒有辦法從(1,1)出發並抵達(n,m)。我們學會了乙個**的法術,這個法術可以把特殊的走道變成牆壁,施法一次的代價為表示該特殊走道的正整數。
假設,我們可以在蜥蜴出發之前不限次數的使用這個**的法術,所花的總代價即為每次施法代價的總和,蜥蜴出發之後就不能再使用這個法術了,請問讓蜥蜴沒辦法達到終點所必須花費的最小總代價是多少呢?
注意,0所代表的走道是無法變為牆壁的。
輸入的第一行有三個正整數q,n,m。代表接下來有q組資料,這q組資料都是n*m的迷宮。
接下來每組資料各n行,代表乙個迷宮,每行各m個整數,第i行中的第j個整數代表迷宮座標(i,j)的格仔。
每一組資料輸出一行,如果無論如何蜥蜴都能到達終點,請在這一行中輸出-1,否則請在這一行中輸出乙個代表答案的整數。
題解:
過不去的條件:可以從左邊界或下邊界建一道連續的牆到右邊界或上邊界。
因為可以斜著走所以牆必須是直接連續,不能是對角線連續(否則依然能過)
這樣之後case通過率55%,因為超時。。。
想了一下,可以對出棧順序進行優化,cost小的先出棧(這樣其實是避免了
一些重複計算,因為cost大的先出棧則後面小的會把他覆蓋,因此前面的
計算是徒勞的)
**:#includeusing namespace std;
#define ll long long
ll a[505][505],tt[505][505];
int n,m,d[4][2]=,,,};
struct node
;bool operator<(const node& a,const node& b)
priority_queuep;
int main()
for(i=1;i<=n;i++)//出發點依次入棧
}for(i=2;i<=m;i++)
}for(i=0;i<=n;i++)
for(j=0;j<=m;j++)
tt[i][j]=1e18;
ll ans=1e18;
while(!p.empty())
if(r.cost>=tt[r.x][r.y])
continue;//剪枝
tt[r.x][r.y]=r.cost;
for(i=0;i<4;i++)
}if(ans==1e18)ans=-1;
printf("%lld\n",ans);
}return 0;
}
Wannafly交流賽1 迷宮2 多源最短路
解題思路 n和m只有500,一開始以為是n 2的dp 後來在紙上畫了一下,能把兩個端點隔開的障礙連起來就是一條由左下邊界走到右上邊界的路徑。要使路徑花費最小。這樣就是乙個很簡單的多源最短路了。include include include include include define lson l,...
Wannafly交流賽1 A 有理數
有乙個問題如下 給你乙個有理數v,請找到小於v的最大有理數。但這個問題的答案對於任意v都是無解的!因為有理數具有稠密性。這意思是,對於任兩個滿足u所以若你說x是答案,那我們總是能找到另外乙個滿足x現在我們不是要問這種只要輸出 no solution 的問題,我們要問乙個稍微難一點的問題如下 給你乙個...
Wannafly交流賽1 牛客網 B 硬幣
蜥蜴的生日快到了,就在這個月底!今年,蜥蜴的快樂夥伴之一壁虎想要送好多個1元硬幣來惡整蜥蜴。壁虎身上目前有的硬幣種類和數量如下 c 1個1元硬幣 c 5個5元硬幣 c 10個10元硬幣 c 50個50元硬幣。壁虎覺得只送c 1個1元硬幣不夠慷慨,想拿一些幣值較大的硬幣去換更多的1元硬幣,於是跑去找一...