CF60B Serial Time! 解题报告
1 题目链接
2 题目大意
题目 : 电视剧时间!
题目大意 :
给定一个 k × n × m k \times n\times m k×n×m的三维空间,问( 1 1 1, x x x, y y y)所在的联通块有多少个小单元立方体。
3 解法分析
这题给出
k
,
n
,
m
∈
[
1
,
10
]
k, n, m \in [1,10]
k,n,m∈[1,10],凭借多年的经验我们知道这道题是可以不当人地暴搜的,只不过是把地图升成了三维、方向数组也由两个变为三个。显然,
d
f
s
dfs
dfs(深度优先搜索)与
b
f
s
bfs
bfs(广度优先搜索)都能做,且都很好做(也许。
1. 深搜
d
f
s
dfs
dfs就是把可能的路径都搜一遍,发现到了一个没走过的格子就++ans
,代码非常好写,缺点就是时间复杂度相对来说会比较高(但这范围小,能过)。
2. 广搜
b
f
s
bfs
bfs每一次都扩展一些点,如果扩展的点不能走或者已经走过了,就不走;否则加进队列,++ans
。时间复杂度为
O
(
k
n
m
)
O(knm)
O(knm),肯定能过。
4 AC代码
4.1 Dalao代码 #001
// From Heart_Blue
// Rating 2425
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>//大佬总喜欢写亿堆头文件,咱也不知道为啥
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 2e2 + 10;
char board[N][N][N];
int flag[N][N][N];
int dx[] = { 0,0,0,0,1,-1 };
int dy[] = { 0,0,1,-1,0,0 };
int dz[] = { 1,-1,0,0,0,0 };//三个方向数组
int k, n, m;
int ans = 0;
void dfs(int x, int y, int z)
{
if (x < 0 || x == k) return;
if (y < 0 || y == n) return;
if (z < 0 || z == m) return;
if (flag[x][y][z]) return;
if (board[x][y][z] == '#') return;//以上其实完全可以一起判断
flag[x][y][z] = 1;//更新标记
ans++;
for (int i = 0; i < 6; i++)
{
dfs(x + dx[i], y + dy[i], z + dz[i]);//接着搜
}
}//十分朴素的dfs
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
cin >> k >> n >> m;
for (int i = 0; i < k; i++)
{
for (int j = 0; j < n; j++)
{
cin >> board[i][j];//char 细节存 string
}
}
int x, y;
cin >> x >> y;
dfs(0, x - 1, y - 1);
cout << ans << endl;
return 0;
}/
4.2 Dalao代码 #002
// From KieranHorgan
// Rating 2190
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n, m, l, ans;
vector<int> a;
string s;
bool visited[11][11][11];
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> l >> n >> m;
for(int i = 0; i < l; i++) {
for(int j = 0; j < n; j++) {
for(int k = 0; k < m; k++) {
char c;
cin >> c;
if(c=='#') visited[i][j][k] = 1;//特殊标记
}
}
}
int t1, t2;
cin >> t1 >> t2;
t1--;
t2--;
queue<pair<int,pair<int,int>>> q;//STL 狂喜
q.push({0,{t1,t2}});
while(!q.empty()) {
pair<int, pair<int, int>> u = q.front();
q.pop();
int x = u.second.first;
int y = u.second.second;
int z = u.first;
// cout << z << " " << x << " " << y << endl;
if(x<0||x>=n || y<0||y>=m || z<0||z>=l || visited[z][x][y]) {
continue;
}
visited[z][x][y] = 1;
ans++;
q.push({z+1,{x,y}});
q.push({z-1,{x,y}});
q.push({z,{x+1,y}});
q.push({z,{x-1,y}});
q.push({z,{x,y+1}});
q.push({z,{x,y-1}});//可以开方向数组(不开费手
}
cout << ans << endl;
}//这个换行看得好累
4.3 蒟蒻代码
#include <cstdio>
#define rep(i, a, b) for (register int (i) = (a); (i) <= (b); ++(i))
int k, n, m, ans, x, y;
char a[17][17][17];
void dfs(int z, int x, int y) {
if (z < 0 || z >= k || x < 0 || x >= n || y < 0 || y >= m || a[z][x][y] == '#')
return;
++ans;
a[z][x][y] = '#';
dfs(z, x, y + 1);
dfs(z, x, y - 1);
dfs(z, x + 1, y);
dfs(z, x - 1, y);
dfs(z + 1, x, y);
dfs(z - 1, x, y);//想了想还是空间复杂度重要一点
}
int main() {
scanf("%d%d%d", &k, &n, &m);
rep(i, 0, k - 1)
rep(j, 0, n - 1)
scanf("%s", a[i][j]);
scanf("%d%d", &x, &y);
dfs(0, x - 1, y - 1);
printf("%d\n", ans);
return 0;
}//本蒟蒻の奇妙码风