nyoj306 走迷宮(搜索+二分)
來源:程序員人生 發布時間:2016-06-29 17:26:45 閱讀次數:2414次
走迷宮
時間限制:1000 ms | 內存限制:65535 KB
難度:5
-
描寫
- Dr.Kong設計的機器人卡多非常愛玩,它常常偷偷跑出實驗室,在某個游樂場玩之不疲。這天卡多又跑出來了,在SJTL游樂場玩個不停,坐完碰碰車,又玩滑滑梯,這時候卡多又走入1個迷宮。整個迷宮是用1個N * N的方陣給出,方陣中單元格中填充了1個整數,表示走到這個位置的難度。
這個迷宮可以向上走,向下走,向右走,向左走,但是不能穿越對角線。走迷宮的取勝規則很成心思,看誰能更快地找到1條路徑,其路徑上單元格最大難度值與最小難度值之差是最小的。固然了,也許這樣的路徑不是最短路徑。
機器人卡多現在在迷宮的左上角(第1行,第1列)而出口在迷宮的右下角(第N行,第N列)。
卡多很聰明,很快就找到了這樣的1條路徑。你能找到嗎?
-
輸入
- 有多組測試數據,以EOF為輸入結束的標志
第1行: N 表示迷宮是N*N方陣 (2≤ N≤ 100)
接下來有N行, 每行包括N個整數,用來表示每一個單元格中難度 (0≤任意難度≤120)。 -
輸出
- 輸出為1個整數,表示路徑上最高難度與和最低難度的差。
-
樣例輸入
-
5
1 1 3 6 8
1 2 2 5 5
4 4 0 3 3
8 0 2 3 4
4 3 0 2 1
-
樣例輸出
-
2
-
來源
- 第4屆河南省程序設計大賽
-
上傳者
- 張云聰
這類思路的確是沒想到
由于這道題的難度范圍是0⑴20 可以對難度2分的方法
由于我深搜超時了 百度找到的思路。
也就是找到1個肯定的難度
#include <stdio.h>
#include <string.h>
int map[105][105];
bool vis[105][105];
int max,min,n;
bool ok;
int dir[4][2]={1,0,⑴,0,0,1,0,⑴};
bool limit(int x,int y)
{
if(vis[x][y]||x<0||y<0||x==n||y==n||ok)
return false;
return true;
}
void dfs(int x,int y,int l,int r)
{
if(x==n⑴&&y==n⑴)
{
ok=true;
return ;
}
for(int i=0;i<4;i++)
{
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(limit(xx,yy)&&map[xx][yy]>=l&&map[xx][yy]<=r)
{
vis[xx][yy]=true;
dfs(xx,yy,l,r);
}
}
}
bool find(int k)
{
for(int i=min;i<=max;i++)
{
if(i+k>max)
break;
if(map[0][0]<i||map[0][0]>i+k) continue;
if(map[n⑴][n⑴]<i||map[n⑴][n⑴]>i+k) continue;
memset(vis,false,sizeof(vis));
ok=false;
dfs(0,0,i,i+k);
if(ok)
return true;
}
return false;
}
int bin_search()
{
int l=0,r=max-min,mid;
while(l<=r)
{
mid=(l+r)/2;
if(find(mid))
r=mid⑴;
else
l=mid+1;
}
return l;
}
int main()
{
while(~scanf("%d",&n))
{
max=-0x3fffffff;
min=0x3fffffff;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&map[i][j]);
max=map[i][j]>max?map[i][j]:max;
min=map[i][j]<min?map[i][j]:min;
}
}
printf("%d\n",bin_search());
}
return 0;
}
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈