2024-01-20自学笔记

2024/1/20 自我学习/练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//P1506 拯救oibh总部
//自己写的(经历了惨痛教训后,记住:数组开大亿点!!!)
#include<bits/stdc++.h>
using namespace std;
struct node{
int x;
int y;
};
int sum;//求和
queue<node> q;//用struct类型,这样就可以即可直接使用队头数据了
int dx[4] = {1,0,0,-1},dy[4] = {0,1,-1,0};//枚举方向
int n,m;
bool f[505][505];//记录已经走过的点
char a[505][505];//保存地图
void bfs()
{
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if((i==1||i==n||j==1||j==m)&&a[i][j]=='0'){//判断总部有没有被淹
q.push((node){i,j});//将(x,y)加入队尾
f[i][j]=1;//标记访问
}
}
}
while(q.size()>0){//队列不为空时操作
node now=q.front();//获取队首元素的值
for(int i=0;i<4;i++){//枚举四个方向
int xx=now.x+dx[i];
int yy=now.y+dy[i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&a[xx][yy]=='0'&&!f[xx][yy]){//如果下一步可走
q.push((node){xx,yy});//又双叒叕是加入队尾
f[xx][yy]=1;//又双叒叕是标记已访问
}
}
q.pop();
}
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];//输入地图
}
}
bfs();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]=='0'&&!f[i][j]) sum++;//如果是总部并且没访问过就总和+1
}
}
cout<<sum<<endl;
return 0;
}
//禁止抄袭!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//P1506 拯救oibh总部
//他人的代码
#include <iostream>
#include <queue>
using namespace std;
bool vis[505][505];
int dx[4] = {1, 0, 0, -1};
int dy[4] = {0, 1, -1, 0};
struct Point
{
int x;
int y;
};
int n,m;
char a[505][505];
queue<Point> q;
void bfs()
{
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if((i==1||i==n||j==1||j==m)&&a[i][j]=='0'){
q.push((Point){i,j});
vis[i][j]=1;
}
}
}
while(q.size()>0){
Point now=q.front();
q.pop();
for(int i=0;i<4;i++){
int nx=now.x+dx[i],ny=now.y+dy[i];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&!vis[nx][ny]&&a[nx][ny]=='0'){
q.push((Point){nx,ny});
vis[nx][ny]=1;
}
}
}
}
int main()
{
cin >> n>>m;
for (int i = 1; i <=n; i++)
for(int j=1;j<=m;j++)
cin >> a[i][j];
bfs();
int sum=0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if(a[i][j]=='0'&&!vis[i][j])
sum++;
cout<<sum;
return 0;
}

学案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//P1443 马的遍历
//看了一下题解才成的(不知道为啥MLE,差点把我电脑搞崩了),查阅了queue的资料
#include <bits/stdc++.h>
using namespace std;
struct node{
int x,y;//结构体存储x,y坐标
};
queue<node> q;//定义一个结构体类型的队列q
int ans[402][402];//记录每个坐标需要的步数
int n,m,sx,sy;
int horse[8][2]={{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};//马下一步能走的八个方向
void bfs(){
while (!q.empty()){//队列不为空
node er=q.front();//取队头元素
int xx=er.x;
int yy=er.y;//将队首的坐标分别赋值给xx,yy变量
for (int i=0;i<8;i++){//枚举8个马的走向
int x=xx+horse[i][0];
int y=yy+horse[i][1];
int sh=ans[xx][yy];//所需步数初始值就等于走到当前位置所需的步数
if (x<1 || x>n ||y<1 ||y>m ||ans[x][y]!=-1) continue;//超出访问限制
ans[x][y]=sh+1;//未continue,这个坐标可以入队,步数+1
node tmp={x,y};
q.push(tmp);//下一步将会走到的新坐标加入队列末尾
}
q.pop();//将队首元素取出
}
}
signed main(){
cin>>n>>m>>sx>>sy;
memset(ans,-1,sizeof(ans));//初始化步数为-1
node tmp={sx,sy};//存放马的初始位置
q.push(tmp);//将初始位置入队
ans[sx][sy]=0;
bfs();
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
printf("%-5d",ans[i][j]);//用标准方法输出,左对齐占5个场宽
}
cout<<endl;//一行结束输出换行
}
return 0;
}
//禁止抄袭!