生活随笔
收集整理的這篇文章主要介紹了
2021算法竞赛入门班第四节课【搜索】练习题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
- Jelly【簡單bfs】
- maze【建圖求最短路】
- wyh的迷宮【BFS】
- 幸運數字Ⅱ【爆搜】
- 迷宮【變種的bfs】
- 走出迷宮【模板dfs】
- 魔法數字【狀態轉移bfs】
Jelly【簡單bfs】
https://ac.nowcoder.com/acm/problem/201613
#include<bits/stdc++.h>
using namespace std
;
const int N
=110;
struct node{int x
,y
,z
,step
;};
char a
[N
][N
][N
];
int st
[N
][N
][N
],n
;
int dx
[6]={-1,0,0,1,0,0};
int dy
[6]={0,1,-1,0,0,0};
int dz
[6]={0,0,0,0,-1,1};
int bfs()
{queue
<node
>q
; q
.push({1,1,1,1});st
[1][1][1]=1;while(q
.size()){auto temp
=q
.front(); q
.pop();int x
=temp
.x
,y
=temp
.y
,z
=temp
.z
,t
=temp
.step
;if(x
==n
&&y
==n
&&z
==n
) return t
;for(int i
=0;i
<6;i
++){int tempx
=x
+dx
[i
];int tempy
=y
+dy
[i
];int tempz
=z
+dz
[i
];if(tempx
<1||tempx
>n
||tempy
<1||tempy
>n
||tempz
<1||tempz
>n
) continue;if(st
[tempz
][tempx
][tempy
]) continue;if(a
[tempz
][tempx
][tempy
]=='*') continue;st
[tempz
][tempx
][tempy
]=1;q
.push({tempx
,tempy
,tempz
,t
+1});}}return -1;
}
int main(void)
{cin
>>n
;for(int i
=1;i
<=n
;i
++)for(int j
=1;j
<=n
;j
++)for(int z
=1;z
<=n
;z
++)cin
>>a
[i
][j
][z
];cout
<<bfs();return 0;
}
maze【建圖求最短路】
https://ac.nowcoder.com/acm/problem/15665
根據題意建圖,跑最短路即可
#include<bits/stdc++.h>
using namespace std
;
const int N
=1010;
const int M
=1e5*4+10;
typedef pair
<int,int> PII
;
int dist
[M
],h
[M
],e
[M
],w
[M
],ne
[M
],idx
,vis
[M
];
string a
[N
];
int n
,m
,t
,st
,ed
;
void init()
{memset(vis
,0,sizeof vis
);memset(h
,-1,sizeof h
);idx
=0;
}
void add(int a
,int b
,int c
)
{e
[idx
]=b
,w
[idx
]=c
,ne
[idx
]=h
[a
],h
[a
]=idx
++;
}
int get(int x
,int y
) {return x
*n
+y
;}
void build(int x
,int y
)
{int dx
[2]={0,1},dy
[2]={1,0};for(int i
=0;i
<2;i
++){int tempx
=x
+dx
[i
];int tempy
=y
+dy
[i
];if(tempx
<0||tempx
>=n
||tempy
<0||tempy
>=m
) continue;if(a
[tempx
][tempy
]=='#') continue;int s1
=get(x
,y
),s2
=get(tempx
,tempy
);add(s1
,s2
,1),add(s2
,s1
,1);}
}
void Dijkstra(int st
)
{memset(dist
,0x3f,sizeof dist
);priority_queue
<PII
,vector
<PII
>,greater
<PII
>>q
; q
.push({0,st
});dist
[st
]=0;while(q
.size()){auto temp
=q
.top(); q
.pop();int u
=temp
.second
;if(vis
[u
]) continue;vis
[u
]=1;for(int i
=h
[u
];i
!=-1;i
=ne
[i
]){int j
=e
[i
];if(dist
[j
]>dist
[u
]+w
[i
]){dist
[j
]=dist
[u
]+w
[i
];q
.push({dist
[j
],j
});}}}
}
int main(void)
{while(cin
>>n
>>m
>>t
){init();for(int i
=0;i
<n
;i
++) cin
>>a
[i
];for(int i
=0;i
<n
;i
++){for(int j
=0;j
<m
;j
++){if(a
[i
][j
]!='#') build(i
,j
);if(a
[i
][j
]=='S') st
=get(i
,j
);if(a
[i
][j
]=='T') ed
=get(i
,j
);}}while(t
--){int x
,y
,xx
,yy
; cin
>>x
>>y
>>xx
>>yy
;if(a
[x
][y
]!='#'&&a
[xx
][yy
]!='#') add(get(x
,y
),get(xx
,yy
),3);}Dijkstra(st
);if(dist
[ed
]>0x3f3f3f3f/2) cout
<<-1<<endl
;else cout
<<dist
[ed
]<<endl
;}return 0;
}
wyh的迷宮【BFS】
https://ac.nowcoder.com/acm/problem/15434
#include<bits/stdc++.h>
using namespace std
;
const int N
=510;
char a
[N
][N
];
int st
[N
][N
],t
,n
,m
;
int stx
,sty
,edx
,edy
;
struct node{int x
,y
,step
;};
int bfs()
{queue
<node
>q
; q
.push({stx
,sty
,0});st
[stx
][sty
]=1;while(q
.size()){auto temp
=q
.front(); q
.pop();int x
=temp
.x
,y
=temp
.y
,t
=temp
.step
;if(x
==edx
&&y
==edy
) return t
;int dx
[4]={-1,0,0,1};int dy
[4]={0,1,-1,0};for(int i
=0;i
<4;i
++){int tempx
=x
+dx
[i
];int tempy
=y
+dy
[i
];if(tempx
<0||tempx
>=n
||tempy
<0||tempy
>=m
) continue;if(a
[tempx
][tempy
]=='x') continue;if(st
[tempx
][tempy
]) continue;st
[tempx
][tempy
]=1;q
.push({tempx
,tempy
,t
+1});}}return -1;
}
int main(void)
{cin
>>t
;while(t
--){cin
>>n
>>m
;memset(st
,0,sizeof st
);for(int i
=0;i
<n
;i
++)for(int j
=0;j
<m
;j
++){cin
>>a
[i
][j
];if(a
[i
][j
]=='s') stx
=i
,sty
=j
;if(a
[i
][j
]=='t') edx
=i
,edy
=j
;}int ans
=bfs();if(ans
!=-1) puts("YES");else puts("NO");}return 0;
}
幸運數字Ⅱ【爆搜】
https://ac.nowcoder.com/acm/problem/15291
先打表,然后二分找到相應的位置,每次計算一段的值。
#include<bits/stdc++.h>
using namespace std
;
typedef long long int LL
;
const int N
=1e5+10;
LL sum
,s
[N
],l
,r
;
vector
<LL
>ve
;
void dfs(LL u
)
{if(u
>1e9) return;ve
.push_back(u
);dfs(u
*10+4);dfs(u
*10+7);
}
int main(void)
{cin
>>l
>>r
;dfs(0);sort(ve
.begin(),ve
.end()); ve
.push_back(4444444444);int L
=lower_bound(ve
.begin(),ve
.end(),l
)-ve
.begin();int R
=lower_bound(ve
.begin(),ve
.end(),r
)-ve
.begin();for(int i
=L
;i
<=R
;i
++){sum
+=(min(ve
[i
],r
)-l
+1)*ve
[i
];l
=ve
[i
]+1;}cout
<<sum
;return 0;
}
迷宮【變種的bfs】
https://ac.nowcoder.com/acm/problem/15136
分為兩種情況:
#include<bits/stdc++.h>
using namespace std
;
const int N
=510;
char a
[N
][N
];
int st
[N
][N
],n
,m
;
int stx
,sty
,endx
,endy
;
int keyx
,keyy
;
struct node{int x
,y
,step
;};
int bfs(int x
,int y
,int endx
,int endy
,int flag
)
{memset(st
,0,sizeof st
);queue
<node
>q
; q
.push({x
,y
,0});st
[x
][y
]=1;int dx
[4]={-1,0,0,1};int dy
[4]={0,-1,1,0};while(q
.size()){auto temp
=q
.front(); q
.pop();int x
=temp
.x
,y
=temp
.y
,u
=temp
.step
;if(x
==endx
&&y
==endy
) return u
;for(int i
=0;i
<4;i
++){int tempx
=x
+dx
[i
];int tempy
=y
+dy
[i
];if(tempx
<0||tempx
>=n
||tempy
<0||tempy
>=m
) continue;if(st
[tempx
][tempy
]) continue;if(a
[tempx
][tempy
]=='W') continue;if(!flag
&&a
[tempx
][tempy
]=='D') continue;st
[tempx
][tempy
]=1;q
.push({tempx
,tempy
,u
+1});}}return 0x3f3f3f3f;
}
int main(void)
{cin
>>n
>>m
;for(int i
=0;i
<n
;i
++)for(int j
=0;j
<m
;j
++){cin
>>a
[i
][j
];if(a
[i
][j
]=='S') stx
=i
,sty
=j
;if(a
[i
][j
]=='E') endx
=i
,endy
=j
;if(a
[i
][j
]=='K') keyx
=i
,keyy
=j
;}int ans1
=bfs(stx
,sty
,endx
,endy
,0);int ans2
=bfs(stx
,sty
,keyx
,keyy
,0)+bfs(keyx
,keyy
,endx
,endy
,1);int ans
=min(ans1
,ans2
);if(ans
>=0x3f3f3f3f) cout
<<-1;else cout
<<ans
;return 0;
}
走出迷宮【模板dfs】
https://ac.nowcoder.com/acm/problem/14572
#include<bits/stdc++.h>
using namespace std
;
const int N
=510;
int st
[N
][N
],n
,m
,stx
,sty
,edx
,edy
;
char a
[N
][N
];
int dx
[4]={-1,0,0,1};
int dy
[4]={0,-1,1,0};
bool dfs(int x
,int y
)
{if(x
==edx
&&y
==edy
) return true;bool flag
=false;st
[x
][y
]=1;for(int i
=0;i
<4;i
++){int tempx
=x
+dx
[i
];int tempy
=y
+dy
[i
];if(tempx
<0||tempx
>=n
||tempy
<0||tempy
>=m
) continue;if(a
[tempx
][tempy
]=='#') continue;if(st
[tempx
][tempy
]) continue;flag
=max(flag
,dfs(tempx
,tempy
));}return flag
;
}
int main(void)
{while(cin
>>n
>>m
){memset(st
,0,sizeof st
);for(int i
=0;i
<n
;i
++)for(int j
=0;j
<m
;j
++){cin
>>a
[i
][j
];if(a
[i
][j
]=='S') stx
=i
,sty
=j
;if(a
[i
][j
]=='E') edx
=i
,edy
=j
;}if(dfs(stx
,sty
)) puts("Yes");else puts("No");}
}
魔法數字【狀態轉移bfs】
https://ac.nowcoder.com/acm/problem/202589
class Solution {
public:int bfs(int n
,int m
){unordered_map
<int,int>mp
;queue
<int>q
; q
.push(n
); mp
[n
]=0;while(q
.size()){auto t
=q
.front(); q
.pop();if(t
==m
) return mp
[t
];int dx
[3]={1,-1,t
*t
-t
};for(int i
=0;i
<3;i
++){int x
=t
+dx
[i
];if(x
<=-10000||x
>3000) continue;if(mp
.count(x
)) continue;q
.push(x
); mp
[x
]=mp
[t
]+1;}}return -1;}int solve(int n
, int m
) {return bfs(n
,m
);}};
總結
以上是生活随笔為你收集整理的2021算法竞赛入门班第四节课【搜索】练习题的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。