第五节 搜索专题 - 1

1|0A. 可可口乐

题目描述

收完玉米之后,小 Q 感觉有些口渴。他去商店买了自己最喜欢的可口可乐。

回到家后,小 Q 眉头一皱,发现事情并不简单,因为瓶身上印着的赫然是“cococala”而不是"cocacola",也就是说他买到的是“可可口乐”。而将第二个"o"和第一个"a"交换之后,"cococala"才会变成“cocacola”。

小 Q 气坏了,他想知道自己买的这瓶饮料和真正的“cocacola”到底相差多少。

即你需要求出:输入字符串通过最少几次字母交换后才能变成“cocacola”。

输入格式

第一行一个长度为 8 的字符串,代表饮料的名字。

输出格式

输出一行一个整数,代表最少的交换次数。

样例输入

cococala

样例输出

1

数据规模

输入字符串长度为 8,且保证有解。

点击查看代码
#include<iostream> #include<algorithm> #include<vector> using namespace std; string t = "cocacola", s; int ans = 8, n = 8; void dfs(int i, int num) { if(num >= ans) return; if(i == n) { ans = num; return; } for(int j = i; j < n; j ++) { if(s[j] == t[i]) { swap(s[i], s[j]); dfs(i + 1, num + (i != j)); swap(s[i], s[j]); } } } int main() { cin >> s; dfs(0, 0); cout << ans; return 0; } 编译结果 compiled successfully time: 2ms, memory: 3516kb, score: 100, status: Accepted > test 1: time: 0ms, memory: 3344kb, points: 10, status: Accepted > test 2: time: 1ms, memory: 3348kb, points: 10, status: Accepted > test 3: time: 0ms, memory: 3516kb, points: 10, status: Accepted > test 4: time: 0ms, memory: 3360kb, points: 10, status: Accepted > test 5: time: 0ms, memory: 3456kb, points: 10, status: Accepted > test 6: time: 0ms, memory: 3512kb, points: 10, status: Accepted > test 7: time: 0ms, memory: 3460kb, points: 10, status: Accepted > test 8: time: 1ms, memory: 3460kb, points: 10, status: Accepted > test 9: time: 0ms, memory: 3280kb, points: 10, status: Accepted > test 10: time: 0ms, memory: 3464kb, points: 10, status: Accepted

2|0B. 郊游

时间:3s 空间:256M

题目描述:

同学们在教室坐好,准备去郊游,他们依次离开教室。同学们的座位由一个 n×n 的矩阵表示,左上角为下标 (1,1) 的同学,右下角为 (n,n),而且座位编号是从左上角到右下角一排排一列列编号的,分别为 1234n2 。第i个离开教室的同学的初始座位是 ai。当前走动的同学可以从当前位置移动到其上下左右 4 个相邻座位之一,当他走到一个非空的座位时会和坐在这个位置上的同学成为好朋友,每个同学都会选择结交最少好朋友的走法离开教室。计算所有好朋友对 (i,j) 的数量 (ij)

输入格式:

第一行包含一个整数 n,表示矩阵大小。

接下来一行包含 n×n 个整数,表示依次离开的同学的初始座位 。

输出格式:

输出一个整数表示答案。

样例1输入:

3 5 2 4 6 8 1 3 7 9

样例1输出:

1

样例2输入:

3 2 5 4 6 8 1 3 7 9

样例2输出:

0

样例3输入:

4 6 7 1 4 13 16 10 9 5 11 12 14 15 2 3 8

样例3输出:

3

约定与提示:

对于 100% 的数据,2n5001ain×n
样例1和2的座位如图:

1 2 3 4 5 6 7 8 9

样例1解释:坐在5号座位的同学先离开教室,他必须经过1,2,3,4,6,7,8,9座位中的一个,所以他必须跟其中1个同学成为朋友。

样例2解释:坐在2号座位的同学先离开教室,接着坐在5号座位的同学离开,他可以经过2号座位离开教室。

样例3的座位如图:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
点击查看代码
#include<iostream> #include<algorithm> #include<vector> #include<string.h> #include<queue> using namespace std; #define int long long #define MAXN 505 int n, ans = 0; bool b[MAXN][MAXN], vis[MAXN][MAXN]; int dx[4] = { -1, 0, 1, 0 }; int dy[4] = { 0, -1, 0, 1 }; int mp[MAXN][MAXN], a[MAXN][MAXN]; void dfs(int x, int y){ for(int i = 0; i < 4; i ++){ int nx = x + dx[i]; int ny = y + dy[i]; if(nx >= 1 && nx <= n && ny >= 1 && ny <= n && !vis[nx][ny]){ if(mp[nx][ny] > mp[x][y] + b[x][y]){ vis[nx][ny] = true; mp[nx][ny] = mp[x][y] + b[x][y]; dfs(nx, ny); vis[nx][ny] = false; } } } } signed main(){ cin >> n; memset(b, 1, sizeof b); for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) mp[i][j] = min(min(i - 1, j - 1), min(n - i, n - j)); for(int i = 1; i <= n; i ++){ for(int j = 1; j <= n; j ++){ cin >> a[i][j]; memset(vis, 0, sizeof vis); int x = (a[i][j] + n - 1) / n, y = a[i][j] - (x - 1) * n; ans += mp[x][y]; b[x][y] = false; vis[x][y] = true; dfs(x, y); } } cout << ans; return 0; } 编译结果 compiled successfully time: 11677ms, memory: 23120kb, score: 100, status: Accepted > test 1: time: 78ms, memory: 6096kb, points: 4, status: Accepted > test 2: time: 244ms, memory: 6692kb, points: 4, status: Accepted > test 3: time: 2514ms, memory: 23120kb, points: 4, status: Accepted > test 4: time: 1ms, memory: 5832kb, points: 4, status: Accepted > test 5: time: 1ms, memory: 5828kb, points: 4, status: Accepted > test 6: time: 1ms, memory: 5932kb, points: 4, status: Accepted > test 7: time: 1ms, memory: 4000kb, points: 4, status: Accepted > test 8: time: 2ms, memory: 3952kb, points: 4, status: Accepted > test 9: time: 1ms, memory: 4048kb, points: 4, status: Accepted > test 10: time: 4ms, memory: 4128kb, points: 4, status: Accepted > test 11: time: 3ms, memory: 3980kb, points: 4, status: Accepted > test 12: time: 4ms, memory: 4000kb, points: 4, status: Accepted > test 13: time: 11ms, memory: 4096kb, points: 4, status: Accepted > test 14: time: 114ms, memory: 4980kb, points: 4, status: Accepted > test 15: time: 121ms, memory: 4892kb, points: 4, status: Accepted > test 16: time: 366ms, memory: 5780kb, points: 5, status: Accepted > test 17: time: 1727ms, memory: 8020kb, points: 5, status: Accepted > test 18: time: 1603ms, memory: 7976kb, points: 5, status: Accepted > test 19: time: 1624ms, memory: 7956kb, points: 5, status: Accepted > test 20: time: 1609ms, memory: 7956kb, points: 5, status: Accepted > test 21: time: 1646ms, memory: 8024kb, points: 5, status: Accepted > test 22: time: 1ms, memory: 5860kb, points: 5, status: Accepted > test 23: time: 1ms, memory: 5884kb, points: 5, status: Accepted

3|0C. 黑白路径

时间:1s 空间:256M

题目描述:

有一个 n×m 的矩阵,矩阵中有两种颜色:黑('#'),白('.')

小信选了一个黑色位置 s,坐标为 (xs,ys)。当小信移动时,他可以往 4 个方向(上下左右)行进,但还有一个要求:假设当前小信从 (x1,y1) 出发,他之后停下的位置坐标为 (x2,y2),要求 (x1,y1)(x2,y2) 的颜色不同。

最终小信会在白色位置 t ,坐标为 (xt,yt) 停下。

请问有多少对 (s,t) 可以从 s 走到 t

输入格式:

第一行包含两个整数 n, m

接下来包含一个 n×m 的矩阵

输出格式:

输出一个整数表示答案。

样例1输入:

4 3 ### ### ... ###

样例1输出:

6

样例2输入:

3 3 .#. ..# #..

样例2输出:

10

约定与提示:

对于 100% 的数据,1n,m400

对于样例1:其中一条路径为 (2,1) -> (3,1)

点击查看代码
#include<iostream> #include<algorithm> #include<vector> #include<string.h> #include<queue> #include<stack> #include<set> using namespace std; #define int long long #define MAXN 405 char mp[MAXN][MAXN]; int n, m, a, b, ans; int dx[4] = { 1, 0, -1, 0 }; int dy[4] = { 0, -1, 0, 1 }; bool vis[MAXN][MAXN]; void dfs(int x, int y) { if(vis[x][y]) return; vis[x][y] = true; if(mp[x][y] == '.') b ++; else a ++; for(int i = 0; i < 4; i ++) { int xx = x + dx[i], yy = y + dy[i]; //printf("(%d, %d) -> (%d, %d)\n", x, y, xx, yy); if(xx > 0 && xx <= n && yy > 0 && yy <= m && mp[xx][yy] != mp[x][y]) dfs(xx, yy); } return; } signed main() { cin >> n >> m; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) cin >> mp[i][j]; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) { a = 0, b = 0; dfs(i, j); ans += a * b; } cout << ans; return 0; } 编译结果 compiled successfully time: 146ms, memory: 16204kb, score: 100, status: Accepted > test 1: time: 0ms, memory: 3468kb, points: 1, status: Accepted > test 2: time: 1ms, memory: 3216kb, points: 1, status: Accepted > test 3: time: 0ms, memory: 3444kb, points: 4, status: Accepted > test 4: time: 0ms, memory: 3400kb, points: 4, status: Accepted > test 5: time: 1ms, memory: 3404kb, points: 4, status: Accepted > test 6: time: 0ms, memory: 3504kb, points: 4, status: Accepted > test 7: time: 0ms, memory: 3356kb, points: 4, status: Accepted > test 8: time: 0ms, memory: 3432kb, points: 4, status: Accepted > test 9: time: 1ms, memory: 3372kb, points: 4, status: Accepted > test 10: time: 1ms, memory: 3368kb, points: 4, status: Accepted > test 11: time: 1ms, memory: 3412kb, points: 4, status: Accepted > test 12: time: 0ms, memory: 3392kb, points: 4, status: Accepted > test 13: time: 9ms, memory: 3764kb, points: 4, status: Accepted > test 14: time: 11ms, memory: 3676kb, points: 4, status: Accepted > test 15: time: 9ms, memory: 3692kb, points: 4, status: Accepted > test 16: time: 8ms, memory: 3736kb, points: 4, status: Accepted > test 17: time: 11ms, memory: 3680kb, points: 4, status: Accepted > test 18: time: 11ms, memory: 3684kb, points: 4, status: Accepted > test 19: time: 10ms, memory: 3732kb, points: 4, status: Accepted > test 20: time: 9ms, memory: 3684kb, points: 4, status: Accepted > test 21: time: 10ms, memory: 3684kb, points: 4, status: Accepted > test 22: time: 10ms, memory: 3680kb, points: 4, status: Accepted > test 23: time: 11ms, memory: 3684kb, points: 4, status: Accepted > test 24: time: 11ms, memory: 3672kb, points: 4, status: Accepted > test 25: time: 6ms, memory: 3764kb, points: 3, status: Accepted > test 26: time: 6ms, memory: 3776kb, points: 3, status: Accepted > test 27: time: 9ms, memory: 16204kb, points: 4, status: Accepted

4|0D. 上学

题目描述

鱼大大就读的学校每天都有检查出勤的楷(e)模(xin)学委。刚巧这天鱼大大起床迟了一些,为了不被这些楷(e)模(xin)学委记录扣分,鱼大大需要挑一条距离最短的小路上学。

身为鱼大大的好朋友,你深知鱼大大的苦楚:鱼大大这个小短腿,每次迈步都只能往上下左右走一格,而学校又在距离鱼大大家直线距离最远的地方(学校在 (n,m) ),要是不好好规划肯定会迟到。于是你便自告奋勇在鱼大大起床刷牙吃早饭的时候,在地图上帮鱼大大选出一条最快到达学校的路程,并告诉鱼大大这条路的距离以及路线。


注:鱼大大的家在地图左上角 (1,1)。起点不算入路径长度

地图上的 # 为坑,会会掉进去,也跨不过去,不能走。

地图大小为 NM

输入格式

第一行两个整数 NM (1<N,M1000)

接下来N行,每行M个字符,表示鱼大大能否通过相应位置的区域。字符只可能是 .#

. 表示鱼大大可以走的路。

# 表示鱼大大不能跨过的坑。

输出格式

第一行一个整数表示路径长度

接下来若干行,每行包含两个用空格隔开的整数,表示鱼大大依次通过的区域的坐标。

如果无法到达学校,输出 1

(若是有多条最短路径,输出其中任何一条即可)

输入样例

5 8 ..#...## #.#.#.## #...#... #.#.#.#. ....#.#.

输出样例

15 1 1 1 2 2 2 3 2 3 3 3 4 2 4 1 4 1 5 1 6 2 6 3 6 3 7 3 8 4 8 5 8
点击查看代码
#include<iostream> #include<algorithm> #include<vector> #include<string.h> #include<queue> #include<stack> using namespace std; #define MAXN 1005 struct node { int qx, qy, num; } b[MAXN][MAXN]; int n, m, a[MAXN][MAXN], l[MAXN], r[MAXN]; char mp[MAXN][MAXN]; bool vis[MAXN][MAXN]; int dx[4] = { 0, -1, 0, 1 }; int dy[4] = { 1, 0, -1, 0 }; stack<node> s; void bfs(int x, int y) { queue<node> q; q.push({x, y, 0}); a[x][y] = q.front().num; vis[x][y] = true; while(!q.empty()) { for(int i = 0; i < 4; i ++) { node p = q.front(); int xx = p.qx + dx[i], yy = p.qy + dy[i]; if(xx <= n && xx >= 1 && yy <= m && yy >= 1 && mp[xx][yy] == '.' && !vis[xx][yy]) { a[xx][yy] = p.num + 1; q.push({xx, yy, a[xx][yy]}); if(!b[xx][yy].qx && !b[xx][yy].qy) b[xx][yy].qx = p.qx, b[xx][yy].qy = p.qy; vis[xx][yy] = true; } } q.pop(); } } int main() { cin >> n >> m; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) cin >> mp[i][j]; bfs(1, 1); if(!a[n][m]) { cout << -1 << endl; return 0; } else cout << a[n][m] << endl; int xx = n, yy = m; while(true) { if(xx == 0 && yy == 0) break; s.push({xx, yy, 0}); int xxx = xx; xx = b[xx][yy].qx, yy = b[xxx][yy].qy; } //cout << sum - 2 << endl; while(!s.empty()) { cout << s.top().qx << " " << s.top().qy << endl; s.pop(); } // for(int i = 1; i <= n; i ++) { // for(int j = 1; j <= m; j ++) { // printf("(%d, %d) ", b[i][j].qx, b[i][j].qy); // } // cout << endl; // } return 0; } 编译结果 compiled successfully time: 154ms, memory: 21032kb, score: 100, status: Accepted > test 1: time: 1ms, memory: 5508kb, points: 10, status: Accepted > test 2: time: 1ms, memory: 5584kb, points: 10, status: Accepted > test 3: time: 0ms, memory: 5432kb, points: 10, status: Accepted > test 4: time: 1ms, memory: 7860kb, points: 10, status: Accepted > test 5: time: 1ms, memory: 8048kb, points: 10, status: Accepted > test 6: time: 0ms, memory: 7952kb, points: 10, status: Accepted > test 7: time: 1ms, memory: 7636kb, points: 10, status: Accepted > test 8: time: 37ms, memory: 18460kb, points: 10, status: Accepted > test 9: time: 46ms, memory: 18768kb, points: 10, status: Accepted > test 10: time: 66ms, memory: 21032kb, points: 10, status: Accepted

5|0E. 锻炼身体的路径

Time Limit: 1000ms Memory Limit: 262144kb

题目描述

题目描述:

有一个 n×m 的地图,空地为 '.',高楼为 '#',小信的家在 'S'。

小信想找一条锻炼身体的路径,路径需要从家出发,不经过相同的空地,最后回到家。出于锻炼身体的目的,这条路径的长度必须至少为 4,也就是说除了终点和起点都是家以外,经过的不同的空地个数至少为 3

小信想知道这样的路径存不存在。当然,小信无法通过有高楼的地方,所以可能不存在这样的路径。

输入格式

第一行包含两个整数 n,m

接下来包含一个 n×m 的地图,地图只包含 '.','#','S' 三种字符。

输出格式

如果存在锻炼身体的路径,输出 "Yes",否则输出 "No"。

样例

Input 1

4 4 .... #.#. #S#. ....

Output 1

Yes

Input 2

4 4 .#.. #.#. #S#. ....

Output 2

No

数据范围

对于 100% 的数据,2n,m1064n·m106

点击查看代码
#include<iostream> #include<algorithm> #include<vector> #include<string.h> #include<queue> #include<stack> #include<set> #include<map> using namespace std; int dx[4] = { 1, -1, 0, 0 }; int dy[4] = { 0, 0, -1, 1 }; int n, m, x, y; map<int, map<int, bool> > mp; map<int, map<int, int> > flag; void dfs(int x, int y, int xd, int yd, int res) { if(x == xd && y == yd && res) if(res >= 4){ cout << "Yes\n"; exit(0); } else return; if(res && res <= flag[x][y]) return; else flag[x][y] = res; for(int i = 0; i < 4; i ++) { int xx = x + dx[i], yy = y + dy[i]; if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && mp[xx][yy]) { mp[xx][yy] = false; //printf("(%d, %d) -> (%d, %d) %d\n", x, y, xx, yy, res); dfs(xx, yy, xd, yd, res + 1); mp[xx][yy] = true; } } return; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m; for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { char s; cin >> s; if(s == 'S') x = i, y = j, mp[i][j] = true; else if(s == '#') mp[i][j] = false; else mp[i][j] = true; } } dfs(x, y, x, y, 0); cout<<"No\n"; return 0; } 编译结果 compiled successfully time: 2874ms, memory: 145584kb, score: 100, status: Accepted > test 1: time: 0ms, memory: 3468kb, points: 4, status: Accepted > test 2: time: 1ms, memory: 3380kb, points: 4, status: Accepted > test 3: time: 151ms, memory: 50712kb, points: 4, status: Accepted > test 4: time: 129ms, memory: 50196kb, points: 4, status: Accepted > test 5: time: 156ms, memory: 50820kb, points: 4, status: Accepted > test 6: time: 141ms, memory: 50296kb, points: 4, status: Accepted > test 7: time: 210ms, memory: 50992kb, points: 4, status: Accepted > test 8: time: 129ms, memory: 50428kb, points: 4, status: Accepted > test 9: time: 147ms, memory: 50528kb, points: 4, status: Accepted > test 10: time: 155ms, memory: 50724kb, points: 4, status: Accepted > test 11: time: 0ms, memory: 3540kb, points: 4, status: Accepted > test 12: time: 1ms, memory: 3372kb, points: 4, status: Accepted > test 13: time: 1ms, memory: 3532kb, points: 4, status: Accepted > test 14: time: 243ms, memory: 50252kb, points: 4, status: Accepted > test 15: time: 476ms, memory: 145584kb, points: 4, status: Accepted > test 16: time: 139ms, memory: 51548kb, points: 4, status: Accepted > test 17: time: 114ms, memory: 37044kb, points: 4, status: Accepted > test 18: time: 50ms, memory: 22052kb, points: 4, status: Accepted > test 19: time: 106ms, memory: 28940kb, points: 4, status: Accepted > test 20: time: 103ms, memory: 40256kb, points: 4, status: Accepted > test 21: time: 103ms, memory: 31228kb, points: 5, status: Accepted > test 22: time: 64ms, memory: 23068kb, points: 5, status: Accepted > test 23: time: 148ms, memory: 36960kb, points: 5, status: Accepted > test 24: time: 107ms, memory: 39604kb, points: 5, status: Accepted

__EOF__

本文作者So_noSlack
本文链接https://www.cnblogs.com/So-noSlack/p/17554874.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   So_noSlack  阅读(303)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示