Fork me on GitHub

UVA11624-Fire!

继续刷邝斌飞搜索专题

UVA11624 (这个邝斌给的链接,但现在UVA官网只能进主页,题目页换新地址了,需要开tizi,懒得开,直接看洛谷吧)

洛谷

 

再一次印证原汁原味英文比翻译好,真按照翻译里的这句:“当Joe走到一个迷宫的边界格子时,我们认为他已经出了迷宫”,那第一个样例就应该输出2,同类人

之前学过复杂度,从0开始回顾但不是这时候,感觉这玩意刷点题再回顾比较好,目前为止都是看到题有啥思路就直接写,没管过复杂度的事

 

读完题感觉又是相当简单啊

 

艹写完TLE了

  1 //之前调试代码感觉思维变得缜密了,些许慰藉
  2 #include<stdio.h>
  3 #include<iostream>
  4 #include<string.h>
  5 using namespace std;
  6 char map[1000][1000];
  7 #include<queue>
  8 int T;
  9 int R,C;
 10 int Jx,Jy;
 11 int Fx,Fy;
 12 struct Node{
 13     int x;
 14     int y;
 15     int step;
 16     char thismap[1000][1000];
 17 };
 18 int vis[1001][1001];//由于有vis[Jx][Jy]=1;这句话出现,要开多一个
 19 Node firstnode;
 20 Node thisnode;
 21 Node nextnode;
 22 queue<Node>q;
 23 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
 24 int flag;
 25 int legal(int x,int y);
 26 int main()
 27 {
 28 //    freopen("zhishu.txt","r",stdin);
 29     cin>>T;
 30     while(T--){
 31         memset(vis,0,sizeof(vis));
 32         while(!q.empty())
 33             q.pop();
 34         flag=0;
 35         cin>>R>>C;
 36         getchar();
 37         for(int i=0;i<R;i++){
 38             for(int j=0;j<C;j++){
 39                 cin>>map[i][j];
 40                 firstnode.thismap[i][j]=map[i][j];
 41                 if(map[i][j]=='J'){
 42                     Jx=i;
 43                     Jy=j;
 44                 }
 45                 if(map[i][j]=='F'){
 46                     Fx=i;
 47                     Fy=j;
 48                 }
 49             }
 50             getchar();
 51         }
 52         vis[Jx][Jy]=1;
 53         firstnode.x=Jx;
 54         firstnode.y=Jy;
 55         firstnode.step=0;
 56         q.push(firstnode);
 57 
 58         while(!q.empty()){
 59             if(flag==1)
 60                 break;
 61             thisnode=q.front();
 62             q.pop();
 63             for(int i=0;i<4;i++){
 64                 nextnode.x=thisnode.x+dir[i][0];
 65                 nextnode.y=thisnode.y+dir[i][1];
 66                 if(!legal(nextnode.x,nextnode.y)){//不用走了,能出去,直接输出
 67                     cout<<thisnode.step+1<<endl;
 68                     flag=1;
 69                     break;
 70                 }
 71                 if(legal(nextnode.x,nextnode.y)){//发现可以走
 72                     for(int i=0;i<R;i++)//先别走,更新下着火地图,找到着火的F点,就四个方向都着火,即搞为F
 73                         for(int j=0;j<C;j++)
 74                             nextnode.thismap[i][j]=thisnode.thismap[i][j];
 75 
 76                     for(int i=0;i<R;i++)
 77                         for(int j=0;j<C;j++)
 78                             if(thisnode.thismap[i][j]=='F')
 79                                 for(int k=0;k<4;k++)
 80                                     if(legal(i+dir[k][0],j+dir[k][1]))
 81                                         if(thisnode.thismap[i+dir[k][0]][j+dir[k][1]]=='.')
 82                                             nextnode.thismap[i+dir[k][0]][j+dir[k][1]]='F';
 83 
 84                     //地图已经更新,开始走
 85 //                    这个时候地图要用nextnode.thismap.但注意此时点还是nextnode.x和y
 86                     if(nextnode.thismap[nextnode.x][nextnode.y]=='.'){
 87                         vis[nextnode.x][nextnode.y]=1;
 88                         nextnode.step=thisnode.step+1;
 89 //                        cout<<nextnode.x<<" "<<nextnode.y<<endl;
 90                         q.push(nextnode);
 91                     }
 92                 }
 93             }
 94         }
 95         if(flag==0)
 96             cout<<"IMPOSSIBLE"<<endl;
 97     }
 98 }
 99 int legal(int x,int y)
100 {
101     if(0<=x&&x<R&&0<=y&&y<C)
102         return 1;
103     else
104         return 0;
105 }
View Code

 

我着火更新每次重新都遍历的一遍(就是每个点是个包涵thismap的结构体,出队的点,四个方向走的时候,看当前是啥状态,R*C整个thisnode的thismap地图,跑一遍,如果是'F',就四周起火,赋给新的nextnode的thismap),估计这里TLE了

题解说双BFS参考博客,小启发:BFS先跑一遍这个点几步之后会着火

 

但好奇怪啊,R*C遍历,是F,就压入着火搜索队列,百度查广搜时间复杂度是m+n,那这R*C*(R+C)已经10^9了,如果T是10组数据那就10^10超时了呀

 

依旧TLE

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<string.h>
  4 using namespace std;
  5 char map[1000][1000];
  6 #include<queue>
  7 int T;
  8 int R,C;
  9 int Jx,Jy;
 10 struct Node{
 11     int x;
 12     int y;
 13     int step;
 14 };
 15 int vis[1001][1001];//由于有vis[Jx][Jy]=1;这句话出现,要开多一个
 16 Node firstnode;
 17 Node thisnode;
 18 Node nextnode;
 19 queue<Node>q;
 20 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
 21 int flag;
 22 int legal(int x,int y);
 23 void bfs_F(int x,int y);
 24 int how_many_steps_F[1001][10001];//多少步后点(x,y)会起火
 25 
 26 int main()
 27 {
 28 //    freopen("zhishu.txt","r",stdin);
 29     cin>>T;
 30     while(T--){
 31         memset(vis,0,sizeof(vis));
 32         memset(how_many_steps_F,1,sizeof(how_many_steps_F));
 33         while(!q.empty())
 34             q.pop();
 35         flag=0;
 36         cin>>R>>C;
 37         getchar();
 38         for(int i=0;i<R;i++){
 39             for(int j=0;j<C;j++){
 40                 cin>>map[i][j];
 41                 if(map[i][j]=='J'){
 42                     Jx=i;
 43                     Jy=j;
 44                 }
 45             }
 46             getchar();
 47         }
 48 
 49         for(int i=0;i<R;i++)
 50             for(int j=0;j<C;j++){
 51                 if(map[i][j]=='F'){
 52                     memset(vis,0,sizeof(vis));
 53                     firstnode.x=i;
 54                     firstnode.y=j;
 55                     firstnode.step=0;
 56                 //用不到thismap
 57                     q.push(firstnode);
 58                     bfs_F(i,j);//着火搜索,借用q队列和vis
 59                 }
 60             }
 61 
 62         memset(vis,0,sizeof(vis));//清vis,准备给下面J开始行走用
 63         vis[Jx][Jy]=1;
 64         firstnode.x=Jx;
 65         firstnode.y=Jy;
 66         firstnode.step=0;
 67         q.push(firstnode);
 68 
 69         while(!q.empty()){
 70             if(flag==1)
 71                 break;
 72             thisnode=q.front();
 73             q.pop();
 74             for(int i=0;i<4;i++){
 75                 nextnode.x=thisnode.x+dir[i][0];
 76                 nextnode.y=thisnode.y+dir[i][1];
 77                 if(!legal(nextnode.x,nextnode.y)){//不用走了,能出去,直接输出
 78                     cout<<thisnode.step+1<<endl;
 79                     flag=1;
 80                     break;
 81                 }
 82                 if(legal(nextnode.x,nextnode.y)){//发现可以走
 83 
 84                     if(map[nextnode.x][nextnode.y]=='.'&&how_many_steps_F[nextnode.x][nextnode.y]>thisnode.step+1&&vis[nextnode.x][nextnode.y]==0){//如果在我之前就着火了,或者即将着火
 85 //                            如果可以走,即将踏出的这一步之前
 86 //                            先看这一步踏出后是不是着火
 87 //                            既不能往已经着火的点里跳,也不能往踏出一步后才会着火的点里跳
 88 
 89                         vis[nextnode.x][nextnode.y]=1;
 90                         nextnode.step=thisnode.step+1;
 91                         q.push(nextnode);
 92                     }
 93                 }
 94             }
 95         }
 96         if(flag==0)
 97             cout<<"IMPOSSIBLE"<<endl;
 98     }
 99 }
100 int legal(int x,int y)
101 {
102     if(0<=x&&x<R&&0<=y&&y<C)
103         return 1;
104     else
105         return 0;
106 }
107 void bfs_F(int x,int y)
108 {
109     while(!q.empty()){
110         thisnode=q.front();
111         q.pop();
112         for(int i=0;i<4;i++){
113             if(legal(thisnode.x+dir[i][0],thisnode.y+dir[i][1])){
114                 nextnode.x=thisnode.x+dir[i][0];
115                 nextnode.y=thisnode.y+dir[i][1];
116                 if(map[nextnode.x][nextnode.y]=='.'){
117                     if(vis[nextnode.x][nextnode.y]==0){
118                         vis[nextnode.x][nextnode.y]=1;
119                         nextnode.step=thisnode.step+1;
120                         if(how_many_steps_F[nextnode.x][nextnode.y]>nextnode.step){
121                             how_many_steps_F[nextnode.x][nextnode.y]=nextnode.step;
122 //                            cout<<"!"<<nextnode.x<<" "<<nextnode.y<<" "<<how_many_steps_F[nextnode.x][nextnode.y]<<endl;
123                             q.push(nextnode);
124                         }
125                     }
126                 }
127             }
128         }
129     }
130 }
View Code

 

我着火bfs是遍历一遍R*C,遇到F就bfs,但看上面超链接里的双BFS博客,是记录下有几个F,一起压进去,记得之前测过,空跑for10^9也会很久,所以估计这里for遍历R*C的时候,10^6先整个进来,就在时间上有点不优秀了

 

想想也确实,我是刷了好几次,F着火地图,有几个就去BFS一次,更新最少着火的how_many_steps_F,vis自然也用了好几次,而双BFS博客里是就刷一遍,vis只用一遍

 

麻痹的,具体时间复杂度我也不懂啊,但感觉会更优化,先按照题解里说的,把所有F都提前存好的这招试试吧

但有更深的感悟就是,写的跟一坨屎的代码思路基本都不是正解,正解基本都清清爽爽

妈的写完还是TLE

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<string.h>
  4 using namespace std;
  5 char map[1000][1000];
  6 #include<queue>
  7 int T;
  8 int R,C;
  9 int Jx,Jy;
 10 struct Node{
 11     int x;
 12     int y;
 13     int step;
 14 };
 15 int vis[1001][1001];//由于有vis[Jx][Jy]=1;这句话出现,要开多一个
 16 Node firstnode;
 17 Node thisnode;
 18 Node nextnode;
 19 queue<Node>q;
 20 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
 21 int flag;
 22 int legal(int x,int y);
 23 void bfs_F();
 24 int how_many_steps_F[1001][10001];//多少步后点(x,y)会起火
 25 int num_of_F;
 26 int Fx[1000];
 27 int Fy[1000];//Fx[0]=7,Fy[0]=3 表示,第0个F坐标为(7,3)
 28 int main()
 29 {
 30 //    freopen("zhishu.txt","r",stdin);
 31     cin>>T;
 32     while(T--){
 33         num_of_F=0;
 34         memset(Fx,0,sizeof(Fx));
 35         memset(Fy,0,sizeof(Fy));
 36         memset(vis,0,sizeof(vis));
 37         memset(how_many_steps_F,1,sizeof(how_many_steps_F));
 38         while(!q.empty())
 39             q.pop();
 40         flag=0;
 41         cin>>R>>C;
 42         getchar();
 43         for(int i=0;i<R;i++){
 44             for(int j=0;j<C;j++){
 45                 cin>>map[i][j];
 46                 if(map[i][j]=='J'){
 47                     Jx=i;
 48                     Jy=j;
 49                 }
 50                 if(map[i][j]=='F'){
 51                     Fx[num_of_F]=i;
 52                     Fy[num_of_F]=j;
 53                     num_of_F++;//比如总共3个F,那num_of_F是3
 54                 }
 55             }
 56             getchar();
 57         }
 58 
 59         bfs_F();//着火搜索,借用q队列和vis
 60 
 61 
 62         memset(vis,0,sizeof(vis));//清vis,准备给下面J开始行走用
 63         vis[Jx][Jy]=1;
 64         firstnode.x=Jx;
 65         firstnode.y=Jy;
 66         firstnode.step=0;
 67         q.push(firstnode);
 68 
 69         while(!q.empty()){
 70             if(flag==1)
 71                 break;
 72             thisnode=q.front();
 73             q.pop();
 74             for(int i=0;i<4;i++){
 75                 nextnode.x=thisnode.x+dir[i][0];
 76                 nextnode.y=thisnode.y+dir[i][1];
 77                 if(!legal(nextnode.x,nextnode.y)){//不用走了,能出去,直接输出
 78                     cout<<thisnode.step+1<<endl;
 79                     flag=1;
 80                     break;
 81                 }
 82                 if(legal(nextnode.x,nextnode.y)){//发现可以走
 83 
 84                     if(map[nextnode.x][nextnode.y]=='.'&&how_many_steps_F[nextnode.x][nextnode.y]>thisnode.step+1&&vis[nextnode.x][nextnode.y]==0){//如果在我之前就着火了,或者即将着火
 85 //                            如果可以走,即将踏出的这一步之前
 86 //                            先看这一步踏出后是不是着火
 87 //                            既不能往已经着火的点里跳,也不能往踏出一步后才会着火的点里跳
 88 
 89                         vis[nextnode.x][nextnode.y]=1;
 90                         nextnode.step=thisnode.step+1;
 91                         q.push(nextnode);
 92                     }
 93                 }
 94             }
 95         }
 96         if(flag==0)
 97             cout<<"IMPOSSIBLE"<<endl;
 98     }
 99 }
100 int legal(int x,int y)
101 {
102     if(0<=x&&x<R&&0<=y&&y<C)
103         return 1;
104     else
105         return 0;
106 }
107 void bfs_F()
108 {
109     for(int i=0;i<num_of_F;i++){
110         firstnode.x=Fx[i];
111         firstnode.y=Fy[i];
112         firstnode.step=0;
113         q.push(firstnode);
114     }
115     while(!q.empty()){
116 
117         thisnode=q.front();
118         q.pop();
119         for(int i=0;i<4;i++){
120             nextnode.x=thisnode.x+dir[i][0];
121             nextnode.y=thisnode.y+dir[i][1];
122             if(legal(nextnode.x,nextnode.y)&&map[nextnode.x][nextnode.y]=='.'&&vis[nextnode.x][nextnode.y]==0){
123                 vis[nextnode.x][nextnode.y]=1;
124                 nextnode.step=thisnode.step+1;
125                 how_many_steps_F[nextnode.x][nextnode.y]=nextnode.step;
126                 q.push(nextnode);
127             }
128         }
129     }
130 }
View Code

 

哦草,惊着我了,数组开大点就AC了!!!

仔细检查发现一点问题没有

AC代码

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<string.h>
  4 using namespace std;
  5 char map[1000][1000];
  6 #include<queue>
  7 int T;
  8 int R,C;
  9 int Jx,Jy;
 10 struct Node{
 11     int x;
 12     int y;
 13     int step;
 14 };
 15 int vis[1001][1001];//由于有vis[Jx][Jy]=1;这句话出现,要开多一个
 16 Node firstnode;
 17 Node thisnode;
 18 Node nextnode;
 19 queue<Node>q;
 20 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
 21 int flag;
 22 int legal(int x,int y);
 23 void bfs_F();
 24 int how_many_steps_F[1000][1000];//多少步后点(x,y)会起火  开小了会RE
 25 int num_of_F;
 26 int Fx[150];//开小了会TLE,不能再小了   记录着有多少个F,这题我测试发现,有超过100个但不到150个的F,直接开了150个肯定够了  这个跟之前提过的一样,开小了会出现RE/TLE各种报错,针对这个来说就是如果开了100个,会有类似把值赋给Fx[110]的操作导致TLE.但之前记得字符串数组越界没啥事,暂且搁置不管那个了
 27 int Fy[150];//Fx[0]=7,Fy[0]=3 表示,第0个F坐标为(7,3)
 28 int main()
 29 {
 30 //    freopen("zhishu.txt","r",stdin);
 31     cin>>T;
 32     while(T--){
 33         num_of_F=0;
 34         memset(Fx,0,sizeof(Fx));
 35         memset(Fy,0,sizeof(Fy));
 36         memset(vis,0,sizeof(vis));
 37         memset(how_many_steps_F,1,sizeof(how_many_steps_F));
 38         while(!q.empty())
 39             q.pop();
 40         flag=0;
 41         cin>>R>>C;
 42         getchar();
 43         for(int i=0;i<R;i++){
 44             for(int j=0;j<C;j++){
 45                 cin>>map[i][j];
 46                 if(map[i][j]=='J'){
 47                     Jx=i;
 48                     Jy=j;
 49                 }
 50                 if(map[i][j]=='F'){
 51                     Fx[num_of_F]=i;
 52                     Fy[num_of_F]=j;
 53                     num_of_F++;//比如总共3个F,那num_of_F是3
 54                 }
 55             }
 56             getchar();
 57         }
 58 
 59         bfs_F();//着火搜索,借用q队列和vis
 60 
 61 
 62         memset(vis,0,sizeof(vis));//清vis,准备给下面J开始行走用
 63         vis[Jx][Jy]=1;
 64         firstnode.x=Jx;
 65         firstnode.y=Jy;
 66         firstnode.step=0;
 67         q.push(firstnode);
 68 
 69         while(!q.empty()){
 70             if(flag==1)
 71                 break;
 72             thisnode=q.front();
 73             q.pop();
 74             for(int i=0;i<4;i++){
 75                 nextnode.x=thisnode.x+dir[i][0];
 76                 nextnode.y=thisnode.y+dir[i][1];
 77                 if(!legal(nextnode.x,nextnode.y)){//不用走了,能出去,直接输出
 78                     cout<<thisnode.step+1<<endl;
 79                     flag=1;
 80                     break;
 81                 }
 82                 if(legal(nextnode.x,nextnode.y)){//发现可以走
 83 
 84                     if(map[nextnode.x][nextnode.y]=='.'&&how_many_steps_F[nextnode.x][nextnode.y]>thisnode.step+1&&vis[nextnode.x][nextnode.y]==0){//如果在我之前就着火了,或者即将着火
 85 //                            如果可以走,即将踏出的这一步之前
 86 //                            先看这一步踏出后是不是着火
 87 //                            既不能往已经着火的点里跳,也不能往踏出一步后才会着火的点里跳
 88 
 89                         vis[nextnode.x][nextnode.y]=1;
 90                         nextnode.step=thisnode.step+1;
 91                         q.push(nextnode);
 92                     }
 93                 }
 94             }
 95         }
 96         if(flag==0)
 97             cout<<"IMPOSSIBLE"<<endl;
 98     }
 99 }
100 int legal(int x,int y)
101 {
102     if(0<=x&&x<R&&0<=y&&y<C)
103         return 1;
104     else
105         return 0;
106 }
107 void bfs_F()
108 {
109     for(int i=0;i<num_of_F;i++){
110         firstnode.x=Fx[i];
111         firstnode.y=Fy[i];
112         firstnode.step=0;
113         q.push(firstnode);
114     }
115     while(!q.empty()){
116 
117         thisnode=q.front();
118         q.pop();
119         for(int i=0;i<4;i++){
120             nextnode.x=thisnode.x+dir[i][0];
121             nextnode.y=thisnode.y+dir[i][1];
122             if(legal(nextnode.x,nextnode.y)&&map[nextnode.x][nextnode.y]=='.'&&vis[nextnode.x][nextnode.y]==0){
123                 vis[nextnode.x][nextnode.y]=1;
124                 nextnode.step=thisnode.step+1;
125                 how_many_steps_F[nextnode.x][nextnode.y]=nextnode.step;
126                 q.push(nextnode);
127             }
128         }
129     }
130 }

这样严谨的开数组,比无脑开数组的好处就是知道哪个地方开小了会产生什么问题,更加透彻理解代码逻辑,为了以后可以无脑开数组

就像学数学是为了,不是买菜用不上就不学,相反数学学好了为了买菜不用数学,可以不用有顾虑的花销,不用计算手头还有多少钱

 

记录坎坷:

###:写着火地图更新的时候,注意别把所有的 '.' 一次全弄成 'F’ 了

###:突然想了下BFS时间复杂度,怎么感觉是m*n呢?先不考虑复杂度

###:除了思考之前BUPT导师批改初试手写代码、吴师兄看代码,还有大型工程项目是怎么修改的,怎么让不同人接手维护的,我自己代码一星期后都看不懂,也不咋好加东西,只有趁热乎才能修改

###:最大值先用memset 1来弄

###:洛谷讨论区给出的几个样例

###:麻痹的之前跟那些把Ctrl+C,Ctrl+S快捷键记录到便利贴上,放电脑屏幕前的傻逼女测试一起干银行外包测试,真他妈耻辱,艹,老子离职学开发,19~23年的4年梦魇我会夺回来,28岁才工作一年,哎

###:本来想看看讨论区那些TLE的帮他们改改,结果发现真看不懂

###:这题好小众

###:走了这么多弯路,不希望别人再走我这样坎坷的路,如果有看不懂的可以留言,看到后会弄个视频讲解,现场写

posted @ 2024-10-04 02:59  GerJCS  阅读(5)  评论(0编辑  收藏  举报