【模拟8.07】走格子

这题一定是个模拟题......

怎么可能.......考场被完美骗到

其实这题是最短路问题啦啦啦啦..........

对于每个墙与墙,我们因为联通的门的存在,所以我们直接将与它相邻的格子连在一起喽

当然暴搜也能骗到85分......

不说了,就当复习一边堆优化dijkstar了....

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<string>
  7 #include<map>
  8 #include<vector>
  9 #include<queue>
 10 #include<set>
 11 #define MAXN 1010
 12 #define ps push_back
 13 #define int long long
 14 using namespace std;
 15 struct node{int to,n,w;}e[250001*42];int head[350001],tot1;
 16 void add(int u,int v,int w)
 17 {
 18      e[++tot1].to=v;e[tot1].n=head[u];e[tot1].w=w;head[u]=tot1;
 19 }
 20 int a[MAXN][MAXN];int n,m;
 21 queue<int>q;
 22 set<int>hang[MAXN],lie[MAXN];
 23 void find_pre(int th,int &x,int &y)
 24 {
 25     if(th%m==0)
 26     {
 27        y=m;
 28        x=th/m;
 29        return ;
 30     }
 31     y=th%m; 
 32     x=th/m+1;
 33 }
 34 int find_sur(int l,int r)
 35 {
 36     return (l-1)*m+r;
 37 }
 38 bool bian[MAXN*MAXN];
 39 void g_kx(int one,int l,int r,int x)
 40 {
 41     if(l>n||l<1)return ;
 42     if(r>m||r<1)return ;
 43     if(a[l][r]==0)
 44     {
 45         add(x,one,1);
 46         add(one,x,1);
 47         if(bian[one]==0)
 48         { 
 49            q.push(one);
 50            bian[one]=1;
 51         }
 52         //printf("1--l=%lld r=%lld x_l=%lld x_r=%lld\n",l,r,l,r);   
 53     }
 54     return ;
 55 }
 56 void BFS(int top)
 57 {
 58      q.push(top);bian[top]=1;
 59      while(!q.empty())
 60      {
 61            int x=q.front();q.pop();
 62            int l;int r;
 63            find_pre(x,l,r);
 64            //printf("%lld %lld\n",l,r);
 65            int one=find_sur(l-1,r),two=find_sur(l,r-1);
 66            int three=find_sur(l+1,r),four=find_sur(l,r+1);
 67            //printf("one=%lld two=%lld\n",one,two);      
 68            g_kx(one,l-1,r,x);g_kx(two,l,r-1,x);
 69            g_kx(three,l+1,r,x);g_kx(four,l,r+1,x);
 70      }
 71 }
 72 int one1,two1,three1,four1;
 73 int minn;
 74 void the_walk_sur(int i,int j,int x)
 75 {
 76        set<int>::iterator it,it2;
 77        it=it2=hang[i].upper_bound(x);
 78        it2--;
 79        one1=*it;two1=*it2;
 80        two1++;one1--;//one 右 two 左
 81        int l,r;
 82        find_pre(one1,l,r);minn=min(minn,r-j+1);
 83        find_pre(two1,l,r);minn=min(minn,j-r+1);
 84       // printf("one1=%lld two1=%lld\n",one1,two1);
 85        it=it2=lie[j].upper_bound(x);
 86        it2--;
 87        three1=*it;four1=*it2;four1+=m;three1-=m;
 88        find_pre(three1,l,r);minn=min(minn,l-i+1);
 89        find_pre(four1,l,r);minn=min(minn,i-l+1);
 90        //three 上 four 下
 91 }
 92 int fir_x,fir_y,end_x,end_y;
 93 char c[MAXN][MAXN];
 94 int dis[MAXN*MAXN];
 95 priority_queue<pair<int,int> >qq;
 96 void connect(int x,int to,int w)
 97 {
 98     if(dis[to]>dis[x]+w)
 99     {
100         dis[to]=dis[x]+w;
101         bian[to]=1;
102         qq.push(make_pair(-dis[to],to));
103         int l,r;find_pre(to,l,r);
104         //printf("connect x=%lld to=%lld l=%lld r=%lld\n",x,to,l,r);
105     }
106 }
107 void diss(int x)
108 {
109      dis[x]=0;
110      qq.push(make_pair(dis[x],x));
111      while(!qq.empty())
112      {
113           int id=qq.top().second;int mm=qq.top().first;
114           int l,r;find_pre(id,l,r);
115           //printf("----id=%lld l=%lld r=%lld %lld\n",id,l,r,-mm);
116           bian[id]=0;
117           qq.pop();
118           minn=1000000000;
119           the_walk_sur(l,r,id);
120           if(minn<1000000000)
121           {
122              connect(id,one1,minn);
123              connect(id,two1,minn);
124              connect(id,three1,minn);
125              connect(id,four1,minn);
126           }
127           for(int i=head[id];i;i=e[i].n)
128           {
129               int to=e[i].to;
130               find_pre(to,l,r);
131               //printf("dis[%lld]=%lld %lld %lld\n",to,dis[to],l,r);    
132               if(dis[id]+e[i].w<dis[to])
133               {
134                   dis[to]=dis[id]+e[i].w;
135                   bian[to]=1;
136                   find_pre(to,l,r); 
137                   //printf("dis[%lld]=%lld %lld %lld\n",to,dis[to],l,r);
138                   qq.push(make_pair(-dis[to],to));
139               }          
140           }
141      }
142 }
143 signed main()
144 {
145     scanf("%lld%lld",&n,&m);
146     memset(dis,0x3f3f3f,sizeof(dis));
147     for(int i=1;i<=n;++i)
148     {
149         for(int j=1;j<=m;++j)
150         {
151             cin>>c[i][j];
152             if(c[i][j]=='#')
153             {
154                a[i][j]=1;
155                hang[i].insert(find_sur(i,j));
156                lie[j].insert(find_sur(i,j));
157             }
158             if(c[i][j]=='C')
159             {
160                fir_x=i;fir_y=j;           
161             }      
162             if(c[i][j]=='F')
163             {
164                end_x=i;end_y=j;
165             }
166         }
167     }
168     BFS(find_sur(fir_x,fir_y));
169     memset(bian,0,sizeof(bian));
170     diss(find_sur(fir_x,fir_y));
171     int anss=dis[find_sur(end_x,end_y)];
172     if(anss==4557430888798830399)
173           printf("no\n");
174     else 
175           printf("%lld\n",anss);
176 }
177 /*
178 15 15
179 ###############
180 #......#....#.#
181 #.......#.....#
182 ##.....#.#...##
183 #..##.........#
184 #.#...##....#.#
185 #........#..#.#
186 #...........#.#
187 #...##...##.F.#
188 #....#.##..##.#
189 ##..C........##//11
190 ###........##.#
191 ###...........#
192 #..##.........#
193 ###############
194 */
View Code

 

posted @ 2019-08-09 19:02  Wwb_star  阅读(143)  评论(0编辑  收藏  举报