《隨機題庫練習10》D

2021-10-05 12:44:47 字數 3177 閱讀 4975

hdu4166的乙個高階版吧.

思路:首先聯想到bfs的性質.

當我們搜素到(x,y)點時,那麼這時的距離一定是到這個點最短的距離.

對於到x點的最短距離,可能會存在多個點到它的距離滿足到x的最短距離.

但是這樣的情況只是說明最短的路徑很多,但是到x點的最短距離肯定是不變的.

因為從x->y的最短路徑肯定是優於(其他到x的》最短路徑的距離)->y的距離.

所以說我們只需要統計到這個點的路徑和到這個點的最短路徑相同的點,那麼就說明可以構成一條最短路徑.

然後聯絡起bfs的性質,當我們第一次搜素到這個點時,最短距離肯定就是這個距離.

然後最後進行一下判斷,注意的是方向不同也算不同的狀態.

然後方案數採用dp轉移.

這裡可以任意走x步,那麼直接從1開始列舉步數.如果碰到炸彈或者出界,那麼就說明不能再往前了,就退出該次迴圈.

#include

using

namespace std;

typedef

long

long ll;

typedef pair<

int,

int> pii;

const

int n =

105;

const

int mod =

1e6;

#define pi acos(-1)

#define inf 1e8

#define inm int_min

#define pb(a) push_back(a)

#define mk(a,b) make_pair(a,b)

#define dbg(x) cout << "now this num is " << x << endl;

#define met0(axx) memset(axx,0,sizeof(axx));

#define metf(axx) memset(axx,-1,sizeof(axx));

#define sd(ax) scanf("%d",&ax)

#define sld(ax) scanf("%lld",&ax)

#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)

#define sdd(ax,bx) scanf("%d %d",&ax,&bx)

#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)

#define sfd(ax) scanf("%lf",&ax)

#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)

#define pr(a) printf("%d\n",a)

#define plr(a) printf("%lld\n",a)

int ex,ey,sx,sy,sz,minn =-1

,ans,n,m;

string mp[

1005];

int b[4]

[2]=

,dis[

1005][

1005][

4];ll cnt[

1005][

1005][

4];//到i,j位置時且朝向為z時的方案數.

map<

char

,int

> mp1;

struct node

;void

init()

intcheck1

(int z)

//左轉

intcheck2

(int z)

//右轉

void

bfs(

int x,

int y,

int z)

else

if(dis[q.x]

[q.y]

[q.z]+1

== dis[px]

[py]

[pz]

) cnt[px]

[py]

[pz]

=(cnt[px]

[py]

[pz]

+cnt[q.x]

[q.y]

[q.z]

)%mod;

px = q.x,py = q.y,pz =

check2

(q.z)

;//右轉

if(dis[px]

[py]

[pz]==-

1)else

if(dis[q.x]

[q.y]

[q.z]+1

== dis[px]

[py]

[pz]

) cnt[px]

[py]

[pz]

=(cnt[px]

[py]

[pz]

+cnt[q.x]

[q.y]

[q.z]

)%mod;

for(

int k=1;

;k++

)else

if(dis[q.x]

[q.y]

[q.z]+1

== dis[px]

[py]

[pz]

) cnt[px]

[py]

[pz]

=(cnt[px]

[py]

[pz]

+cnt[q.x]

[q.y]

[q.z]

)%mod;

}else

break

;//當遇到不能走時,或者走到邊界時退出.}}

for(

int i=

0;i<4;

++i)

if(dis[ex]

[ey]

[i]!=-1

) ans =

min(ans,dis[ex]

[ey]

[i]);if

(ans == inf)

printf

("0 0\n");

else

}int

main()

}bfs

(sx,sy,sz);}

system

("pause");

return0;

}

《隨機題庫練習10》G

思路 看題就想到了拓撲.但是由於這裡可以同時進行多個安裝.所以我先跑了一次dfs.果然超時了 首先這個答案肯定是有向邊的最長邊集的長度。邊的長度為安裝時間 那麼如果直接上拓撲,記錄安裝到每乙個點的時間,然後通過前驅點不斷轉移。這樣是不行的.因為可能會存在多個前驅點。我們需要取最長的前驅點作為開始安裝...

Python 題庫練習七

what gets printed?nums set 1,1,2,3,3,3,4 print len nums 題目解析 這題考察set方法的特性 在jupter notebook中敲入相應 執行,看結果 nums set 1 1,2 3,3 3,4 print len nums 執行結果 4set...

LeetCode 題庫練習 2

題目 給出兩個 非空 的鍊錶用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式儲存的,並且它們的每個節點只能儲存 一位 數字。如果,我們將這兩個數相加起來,則會返回乙個新的鍊錶來表示它們的和。您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。示例 輸入 2 4 3 5 6 4 ...