iscsi

cc 2012 02 smvsevil

Feb 6th, 2012
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.74 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <sstream>
  4. #include <string>
  5. #include <vector>
  6. #include <queue>
  7. #include <set>
  8. #include <map>
  9. #include <cstdio>
  10. #include <cstdlib>
  11. #include <cctype>
  12. #include <cmath>
  13. #include <cstring>
  14. #include <ctime>
  15. #include <cassert>
  16. using namespace std;
  17. typedef unsigned long long LL;
  18. #define FOR(k,a,b) for(LL k(a); k < (b); ++k)
  19. #define FORD(k,a,b) for(int k(b-1); k >= (a); --k)
  20. #define REP(k,a) for(int k=0; k < (a); ++k)
  21. #define ABS(a) ((a)>0?(a):-(a))
  22. #ifdef HOME
  23. #include "debug.h"
  24. #else
  25. #define debug()
  26. #endif
  27.  
  28. class MAZE
  29. {
  30.     int mHeight;
  31.     int mWidth;
  32.     vector<vector<bool> > mMaze;
  33.     int mActX;
  34.     int mActY;
  35.     int mEndX;
  36.     int mEndY;
  37.     vector<vector<int> > mDistToEnd;
  38.     vector<vector<string> > mPath;
  39. public:
  40.     MAZE(vector<vector<bool> >& maze, int startx, int starty, int endx, int endy):
  41.       mActX(startx+1),
  42.           mActY(starty+1),
  43.           mEndX(endx+1),
  44.           mEndY(endy+1)
  45.       {
  46.           mMaze.swap(maze);
  47.           mHeight=mMaze.size();
  48.           mWidth=mMaze[0].size();
  49.           //calculate dist to end
  50.           mDistToEnd.resize(mHeight,vector<int> (mWidth, 10000));
  51.           mPath.resize(mHeight,vector<string> (mWidth));
  52.           mDistToEnd[mEndY][mEndX]=0;
  53.           bool improve=true;
  54.           while(improve)
  55.           {
  56.               improve=false;
  57.               REP(i,mWidth)
  58.                   REP(j,mHeight)
  59.                   if(mMaze[j][i])
  60.                   {
  61.                       if(mDistToEnd[j][i-1]+1<mDistToEnd[j][i])
  62.                       {
  63.                           mDistToEnd[j][i]=mDistToEnd[j][i-1]+1;
  64.                           mPath[j][i]=mPath[j][i-1]+'W';
  65.                           improve=true;
  66.                       }
  67.                       if(mDistToEnd[j][i+1]+1<mDistToEnd[j][i])
  68.                       {
  69.                           mDistToEnd[j][i]=mDistToEnd[j][i+1]+1;
  70.                           mPath[j][i]=mPath[j][i+1]+'E';
  71.                           improve=true;
  72.                       }
  73.                       if(mDistToEnd[j-1][i]+1<mDistToEnd[j][i])
  74.                       {
  75.                           mDistToEnd[j][i]=mDistToEnd[j-1][i]+1;
  76.                           mPath[j][i]=mPath[j-1][i]+'N';
  77.                           improve=true;
  78.                       }
  79.                       if(mDistToEnd[j+1][i]+1<mDistToEnd[j][i])
  80.                       {
  81.                           mDistToEnd[j][i]=mDistToEnd[j+1][i]+1;
  82.                           mPath[j][i]=mPath[j+1][i]+'S';
  83.                           improve=true;
  84.                       }
  85.                   }
  86.           }
  87.           REP(i,mWidth)
  88.               REP(j,mHeight)
  89.               reverse(mPath[j][i].begin(),mPath[j][i].end());
  90.       }
  91.       int GetActDist()
  92.       {
  93.           return mDistToEnd[mActY][mActX];
  94.       }
  95.       const string& GetPath()
  96.       {
  97.           return mPath[mActY][mActX];
  98.       }
  99.       void Step(const string& s)
  100.       {
  101.           REP(i,s.size())
  102.           {
  103.               switch(s[i])
  104.               {
  105.               case 'W':
  106.                   if(mMaze[mActY][mActX-1])
  107.                       --mActX;
  108.                   break;
  109.               case 'E':
  110.                   if(mMaze[mActY][mActX+1])
  111.                       ++mActX;
  112.                   break;
  113.               case 'N':
  114.                   if(mMaze[mActY-1][mActX])
  115.                       --mActY;
  116.                   break;
  117.               case 'S':
  118.                   if(mMaze[mActY+1][mActX])
  119.                       ++mActY;
  120.                   break;
  121.               default:
  122.                   assert(false);
  123.               }
  124.           }
  125.       }
  126.       int StepCalc(const string& s) const
  127.       {
  128.           int x=mActX,y=mActY;
  129.           REP(i,s.size())
  130.           {
  131.               switch(s[i])
  132.               {
  133.               case 'W':
  134.                   if(mMaze[y][x-1])
  135.                       --x;
  136.                   break;
  137.               case 'E':
  138.                   if(mMaze[y][x+1])
  139.                       ++x;
  140.                   break;
  141.               case 'N':
  142.                   if(mMaze[y-1][x])
  143.                       --y;
  144.                   break;
  145.               case 'S':
  146.                   if(mMaze[y+1][x])
  147.                       ++y;
  148.                   break;
  149.               default:
  150.                   assert(false);
  151.               }
  152.           }
  153.           return mDistToEnd[y][x];
  154.       }
  155. };
  156.  
  157. int main()
  158. {
  159. #ifdef HOME
  160.     clock_t start=clock();
  161.     freopen ("in.txt","r",stdin);
  162.     freopen ("out.txt","w",stdout);
  163.     freopen ("out_err.txt","w",stderr);
  164. #endif
  165.     std::ios_base::sync_with_stdio (false);
  166.     int T,K,M,N;
  167.     cin >> T;
  168.     REP(testcase,T)
  169.     {
  170.         cin >> K;
  171.         string s;
  172.         vector<MAZE> v;
  173.         REP(ttt,K)
  174.         {
  175.             cin >> M >> N;
  176.             int sx, sy, ex, ey;
  177.             vector<vector<bool> > maze(M+2,vector<bool> (N+2,false));
  178.             REP(i,M)
  179.             {
  180.                 cin >> s;
  181.                 REP(j,N)
  182.                 {
  183.                     switch(s[j])
  184.                     {
  185.                     case 'S':
  186.                         maze[i+1][j+1]=true;
  187.                         sx=j,sy=i;
  188.                         break;
  189.                     case 'E':
  190.                         maze[i+1][j+1]=true;
  191.                         ex=j,ey=i;
  192.                         break;
  193.                     case '.':
  194.                         maze[i+1][j+1]=true;
  195.                         break;
  196.                     }
  197.                 }
  198.             }
  199.             v.push_back(MAZE(maze,sx,sy,ex,ey));
  200.         }
  201.         vector<bool> used(K);
  202.         string out;
  203.         REP(round,K)
  204.         {
  205.  
  206.             int best=-1,bestscore=100000;;
  207.             REP(i,K)
  208.                 if(!used[i])
  209.                 {
  210.                     best=i;
  211.                     break;
  212.                 }
  213.                 REP(i,K)
  214.                 {
  215.                     if(!used[i])
  216.                     {
  217.                         int scorei=v[i].GetActDist();
  218.                         const string& acts=v[i].GetPath();
  219.                         REP(j,K)
  220.                             if(!used[j] && j!=i && scorei+v[j].StepCalc(acts)<bestscore)
  221.                             {
  222.                                 best=i;
  223.                                 bestscore=scorei+v[j].StepCalc(acts);
  224.                             }
  225.                     }
  226.                 }
  227.                 assert(!used[best]);
  228.                 const string& acts=v[best].GetPath();
  229.                 REP(i,K)
  230.                     if(!used[i])
  231.                         v[i].Step(acts);
  232.                 out+=acts;
  233.                 used[best]=true;
  234.         }
  235.         cout << out << endl;
  236.     }
  237. #ifdef HOME
  238.     fprintf(stderr,"time=%.3lfsec\n",0.001*(clock()-start));
  239. #endif
  240.     return 0;
  241. }
Advertisement
Add Comment
Please, Sign In to add comment