BFS——关于洛谷P1331海战的思考

  题目链接:https://www.luogu.com.cn/problem/P1331

  解题的主要思路;1.如何判断是否是Bad placement的情况,这里是先观察到如果是Bad placement必然会有如下结构,其实也蛮好想的,如果是一个整体的船则必然是方形,否则就是多边形,这必然带有如下结                                  构,反过来也一样,然后就两个for循环一个个判断即可。

                             

                            2.如果不是Bad placement,本题目就变换为了求连通块的问题,可以用DFS也可以BFS,这里我选择用BFS。

  AC代码展示:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m;
 4 char s[2000][2000];
 5 int book[2000][2000];
 6 int dis[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
 7 //判断是否碰船了  这个思路值得学习
 8 bool p(){
 9     for(int i=0;i<n;i++){
10         for(int j=0;j<m;j++){
11             if((n-i)>=1&&(m-j)>=1){
12                 int ans=0;
13                 if(s[i][j]=='#'){
14                     ans++;
15                 }
16                 if(s[i][j+1]=='#'){
17                     ans++;
18                 }
19                 if(s[i+1][j]=='#'){
20                     ans++;
21                 }
22                 if(s[i+1][j+1]=='#'){
23                     ans++;
24                 }
25                 if(ans==3){
26                     return false;
27                 }
28             }
29         }
30     }
31     return true;
32 }
33 int main(){
34     scanf("%d%d",&n,&m);
35     getchar();
36     getchar();
37     for(int i=0;i<n;i++){
38         for(int j=0;j<m;j++){
39             scanf("%c",&s[i][j]);
40         }
41         getchar();
42         getchar();
43     }
44     int flag=0;
45     if(!p()){
46         cout<<"Bad placement."<<endl;
47     }else{
48         for(int i=0;i<n;i++){
49             for(int j=0;j<m;j++){
50                 if(book[i][j]==0&&s[i][j]=='#'){
51                     flag++;
52                     queue<int>xx;
53                     queue<int>yy;
54                     xx.push(i);
55                     yy.push(j);
56                     book[i][j]=1;
57                     while(!xx.empty()){
58                         int x1=xx.front();
59                         int y1=yy.front();
60                         xx.pop();
61                         yy.pop();
62                         for(int k=0;k<4;k++){//这里注意不能是i或者j   因为可能会re
63                             int x=x1+dis[k][0];
64                             int y=y1+dis[k][1];
65                             if(book[x][y]==0&&(x>=0&&x<n)&&(y>=0&&y<m)&&s[x][y]=='#'){
66                                 xx.push(x);
67                                 yy.push(y);
68                                 book[x][y]=1;
69                             }
70                         }
71                     }
72                 }
73             }
74         }
75         cout<<"There are "<<flag<<" ships."<<endl;
76         //int   main返回一个非零的数会报错 会runtime erro
77     }
78 }

  注意事项:1.BFS的大概框架:

                    2.有两个getchar()是为了清除缓存区的换行符,linux系统下的换行符为/r/n,而windows中就转化为了一个/n,这就是洛谷提交要用两个getchar(),本地windows则只需要用到一个getchar(),如果不用                      清除缓存区的换行符,就会被scanf(应为是%c,scanf要读入字符)读入,发生错误.

                    3.用scanf一个一个读入字符,比用cin读入string块多了,在大数据面前更加明显.

                    4.main函数不要返回一个非零值,不然洛谷判题机会re(runtime error)

        

 

posted @ 2021-05-07 20:41  江间暮云  阅读(216)  评论(0)    收藏  举报