Advertisement
999ms

ebala

Mar 13th, 2019
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.08 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4.  
  5.  
  6. struct State{  
  7.     int x, y, z, mask;
  8.     State(){
  9.         x=0,y=0,z=0,mask=0;
  10.     }
  11.     State(int xx, int yy, int zz, int mm){
  12.         x = xx;
  13.         y = yy;
  14.         z = zz;
  15.         mask = mm;
  16.     }
  17. };
  18.  
  19. //////////////////////
  20.  
  21.  
  22. const int sz = 1<<23;
  23. int n,m,s;
  24. int depth[sz];
  25. bool exist[sz];
  26. string M[50];
  27. string G[10][50];
  28. vector< vector<int> > change_mask;
  29. vector<vector<int> > change_coordinates;
  30.  
  31. //////////////////////
  32.  
  33. int id(State & st){
  34.     return (st.mask) + (st.x << 10) + (st.y << 16) + (st.z << 22);
  35. }
  36.  
  37. int id(int x, int y, int z, int mask){
  38.     return (mask) + (x << 10) + (y << 16) + (z << 22);
  39. }
  40.  
  41. const string is_switch = "ABCDEFGHIJabcdefghij";
  42.  
  43. bool can_go(State & from, State & to){
  44.     if(!exist[id(from)] || !exist[id(to)]) return false;
  45.     if(__builtin_popcount(abs(from.mask - to.mask))>1) return false;
  46.     if(from.mask == to.mask) {
  47.         int delta = abs(from.x - to.x) + abs(from.y - to.y) + abs(from.z - to.z);
  48.        if(delta!=1) return false;
  49.         return true;
  50.     } else {
  51.         int delta_not_z = abs(from.x - to.x) + abs(from.y - to.y);
  52.         if(delta_not_z > 0)
  53.             return false;
  54.         if(from.z != to.z)
  55.             if(is_switch.find(M[from.x][from.y]) == -1)
  56.                 return false;
  57.        
  58.         return true;
  59.     }
  60. }
  61.  
  62. int check_bit(int & val, int & bit){
  63.     return ((val>>bit)&1);
  64. }
  65.  
  66. int check_coor(int & x, int & y, int & z){
  67.    return x>=0&&y>=0&&z>=0&&x<=n&&y<=m&&z<=1;
  68. }
  69.  
  70. const string upper_string = "ABCDEFGHIJ^";
  71.  
  72. char is_upper(char c){
  73.     return upper_string.find(c) != -1;
  74. }
  75.  
  76.  
  77.  
  78. int main(){
  79.     ios_base::sync_with_stdio(false);
  80.     cin.tie(nullptr);
  81.     cin>>m>>n;
  82.     for(int i=0;i<n;i++){
  83.         cin>>M[i];
  84.     }
  85.     cin>>s;
  86.     for(int g=0;g<s;g++){
  87.         for(int i=0;i<n;i++){
  88.             cin>>G[g][i];
  89.         }
  90.     }
  91.  
  92.     for(int i=0;i<s;i++){
  93.         change_mask.push_back({0,0,0,i});
  94.         change_mask.push_back({0,0,-1,i});
  95.         change_mask.push_back({0,0,1,i});
  96.     }
  97.     change_coordinates.push_back({ 1, 0, 0});
  98.     change_coordinates.push_back({-1, 0, 0});
  99.     change_coordinates.push_back({ 0, 1, 0});
  100.     change_coordinates.push_back({ 0,-1, 0});
  101.     change_coordinates.push_back({ 0, 0, 1});
  102.     change_coordinates.push_back({ 0, 0,-1});
  103.  
  104.     memset(exist, 0, sizeof exist);
  105.  
  106.     for(int mask=0;mask<(1<<s);mask++){
  107.         for(int x=0;x<n;x++){
  108.             for(int y=0;y<m;y++){
  109.                 if(M[x][y]=='#') continue;
  110.                 for(int z=0;z<2;z++){
  111.                     if(M[x][y]=='|'){
  112.                         exist[id(x,y,z,mask)] = 1;
  113.                     }
  114.                 }
  115.         if(M[x][y] == '|') continue;               
  116.                 int z = is_upper(M[x][y]);
  117.                 for(int bit=0;bit<s;bit++){
  118.                     if(check_bit(mask, bit)){
  119.                         if(G[bit][x][y] == '*'){
  120.                             z ^=1;
  121.                         }
  122.                     }
  123.                 }
  124.                 exist[id(x,y,z,mask)] = 1;
  125.             }
  126.         }
  127.     }
  128.      
  129.     int start_x, start_y, finish_x, finish_y;
  130.  
  131.     for(int i=0;i<n;i++){
  132.         for(int j=0;j<m;j++){
  133.             if(M[i][j] == '%'){
  134.                 start_x = i;
  135.                 start_y = j;
  136.             }
  137.             if(M[i][j] == '&'){
  138.                 finish_x = i;
  139.                 finish_y = j;
  140.             }
  141.         }
  142.     }      
  143.  
  144.     State start = State(start_x, start_y, 0, 0);
  145.  
  146.     queue<State> q;
  147.     q.push(start);
  148.  
  149.     memset(depth, 0x3f, sizeof depth);
  150.     depth[id(start_x, start_y, 0, 0)] = 0;
  151.     int cur_x,cur_y,cur_z,cur_mask,nxt_x,nxt_y,nxt_z,nxt_mask, delta_mask, bit;
  152.     while(q.size()){
  153.         State cur = q.front();
  154.         q.pop();
  155.        
  156.         cur_x = cur.x;
  157.         cur_y = cur.y;
  158.         cur_z = cur.z;
  159.         cur_mask = cur.mask;
  160.      
  161.  
  162.         for(auto & v : change_mask){
  163.            nxt_x = cur_x;
  164.             nxt_y = cur_y;
  165.             nxt_z = cur_z + v[2];
  166.             bit = v[3];
  167.             if(!check_coor(nxt_x, nxt_y, nxt_z)) continue;
  168.             nxt_mask = (cur_mask | (1<<v[3]));
  169.             delta_mask = (abs(nxt_mask - cur_mask));
  170.             if(M[cur_x][cur_y] - 'a' != bit && M[cur_x][cur_y] - 'A' != bit) continue;
  171.             State nxt_state = State(nxt_x, nxt_y, nxt_z, nxt_mask);
  172.             if(can_go(cur, nxt_state)){
  173.                 if(depth[id(cur)] + 1 < depth[id(nxt_state)]){
  174.                     depth[id(nxt_state)] = depth[id(cur)] + 1;
  175.                     q.push(nxt_state);
  176.                 }
  177.             }
  178.         }
  179.  
  180.         for(auto & v : change_mask){
  181.             nxt_x = cur_x;
  182.             nxt_y = cur_y;
  183.             nxt_z = cur_z + v[2];
  184.             if(!check_coor(nxt_x, nxt_y, nxt_z)) continue;
  185.             nxt_mask = (cur_mask & ((1<<s)-1-(1<<v[3])));
  186.            
  187.             delta_mask = (abs(nxt_mask - cur_mask));
  188.             bit = 0;
  189.             while((1<<bit) < delta_mask) ++bit;
  190.             if(M[cur_x][cur_y] - 'a' != bit && M[cur_x][cur_y] - 'A' != bit) continue;
  191.            
  192.             State nxt_state = State(nxt_x, nxt_y, nxt_z, nxt_mask);
  193.             if(can_go(cur, nxt_state)){
  194.                 if(depth[id(cur)] + 1 < depth[id(nxt_state)]){
  195.                     depth[id(nxt_state)] = depth[id(cur)] + 1;
  196.                     q.push(nxt_state);
  197.                 }
  198.             }
  199.         }
  200.  
  201.         for(auto & v : change_coordinates){
  202.             nxt_x = cur_x + v[0];
  203.             nxt_y = cur_y + v[1];
  204.             nxt_z = cur_z + v[2];
  205.             if(!check_coor(nxt_x, nxt_y, nxt_z)) continue;
  206.             nxt_mask = cur_mask;
  207.             State nxt_state = State(nxt_x, nxt_y, nxt_z, nxt_mask);
  208.             if(can_go(cur, nxt_state)){
  209.                 if(depth[id(cur)] + 1 < depth[id(nxt_state)]){
  210.                     depth[id(nxt_state)] = depth[id(cur)] + 1;
  211.                     q.push(nxt_state);
  212.                 }
  213.             }
  214.         }
  215.     }
  216.     int ans = depth[0];
  217.     for(int mask = 0; mask < (1<<s); mask++){
  218.         for(int z=0;z<2;z++){
  219.             ans = min(ans, depth[id(finish_x, finish_y, z, mask)]);
  220.         }
  221.     }
  222.     if(ans == depth[0]){
  223.         cout<<-1<<endl;
  224.     }
  225.     else{
  226.         cout<<ans<<endl;
  227.     }
  228.     return 0;
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement