USACO 3.3.3 camelot

来源:互联网 发布:cdr是什么软件 编辑:程序博客网 时间:2024/06/05 23:40

本来这是个简单题,但是两年前第一次做的时候发现它真的太经典了!

 

【camelot】

/*ID: wangqia6TASK: camelotLANG: C++*/#include <fstream>#include <cstring>#include <cmath>#include <algorithm>#include <queue>using namespace std;const long INF = 0x01010100;const long NMAX = 30;const long CMAX = 900;const long KMAX = 8;const long WMAX = 16;const long dx[KMAX] = {1,2,-1,-2,-2,1,2,-1};const long dy[KMAX] = {2,1,-2,-1,1,-2,-1,2};const long cx[KMAX] = {1,-1,1,-1,0,0,1,-1};const long cy[KMAX] = {1,-1,-1,1,1,-1,0,0};const long ex[WMAX] = {2,-2,2,-2,0,0,2,-2,2,2,1,-1,-2,-2,1,-1};const long ey[WMAX] = {2,-2,-2,2,2,-2,0,0,1,-1,2,2,1,-1,-2,-2};const long A = long('A') - 1;struct posi{       long x,y;       };ifstream fin ("camelot.in");ofstream fout ("camelot.out");long n,m,knight_sum = 0,pick_sum = 0,pick_two_sum = 0,     dist[NMAX][NMAX][NMAX][NMAX],dist_sum,ans = INF;bool vis[NMAX][NMAX];posi meet,king,knight[CMAX],pick[KMAX],pick_two[WMAX];queue<long> quex,quey;void initdata(){     char ch;     long t;          fin >> n >> m;     fin >> ch >> king.y;     king.x = long(ch) - A;     while (fin >> ch >> t)     {           knight[knight_sum].x = long(ch) - A;           knight[knight_sum].y = t;           knight_sum++;                 }          return;     }bool check(long a,long b){     if (a < 1)         return false;     if (b < 1)        return false;     if (a > m)        return false;     if (b > n)        return false;     return true;     }void get_dist(long sx, long sy){     long tx,ty,i,px,py,dd;          memset(vis,0,sizeof(vis));      vis[sx][sy] = true;     dist[sx][sy][sx][sy] = 0;          quex.push(sx);     quey.push(sy);     while (! quex.empty())     {           tx = quex.front();           ty = quey.front();           dd = dist[sx][sy][tx][ty];                      for (i = 0; i < KMAX; i++)           {               px = tx + dx[i];               py = ty + dy[i];               if (check(px,py) && (! vis[px][py]))               {                  vis[px][py] = true;                  dist[sx][sy][px][py] = dd + 1;                    quex.push(px);                  quey.push(py);                             }               }                      quex.pop();           quey.pop();     }          return;     }void calc_dist(){     long i,j;          memset(dist,0x0f,sizeof(dist));     for (i = 1; i <= m; i++)         for (j = 1; j <= n; j++)             get_dist(i,j);          return;     }long king_dist(long i,long j){     return max(abs(king.x - i),abs(king.y - j));     }void solve(){     long i,j,new_dist;          for (i = 0; i < KMAX; i++)         if (check(king.x + cx[i],king.y + cy[i]))         {            pick[pick_sum].x = king.x + cx[i];            pick[pick_sum].y = king.y + cy[i];            pick_sum++;         }              for (i = 0; i < WMAX; i++)         if (check(king.x + ex[i],king.y + ey[i]))         {            pick_two[pick_two_sum].x = king.x + ex[i];            pick_two[pick_two_sum].y = king.y + ey[i];            pick_two_sum++;         }          for (meet.x = 1; meet.x <= m; meet.x++)         for (meet.y = 1; meet.y <= n; meet.y++)         {             dist_sum = 0;             for (i = 0; i < knight_sum; i++)             {                 dist_sum += dist[meet.x][meet.y][knight[i].x][knight[i].y];                 if (dist_sum > ans)                    break;                              }             if (dist_sum > ans)                continue;                                if (dist_sum + king_dist(meet.x,meet.y) < ans)                ans = dist_sum + king_dist(meet.x,meet.y);                          for (j = 0; j < knight_sum; j++)             {                 new_dist = dist_sum - dist[knight[j].x][knight[j].y][meet.x][meet.y] +                            dist[knight[j].x][knight[j].y][king.x][king.y] +                            dist[king.x][king.y][meet.x][meet.y];                 if (new_dist < ans)                    ans = new_dist;                 }                             for (i = 0; i < pick_sum; i++)                 for (j = 0; j < knight_sum; j++)                 {                     new_dist = dist_sum - dist[knight[j].x][knight[j].y][meet.x][meet.y] +                                  dist[knight[j].x][knight[j].y][pick[i].x][pick[i].y] +                                 1 + dist[pick[i].x][pick[i].y][meet.x][meet.y];                     if (new_dist < ans)                        ans = new_dist;                     }                                               for (i = 0; i < pick_two_sum; i++)                 for (j = 0; j < knight_sum; j++)                 {                     new_dist = dist_sum - dist[knight[j].x][knight[j].y][meet.x][meet.y] +                                  dist[knight[j].x][knight[j].y][pick_two[i].x][pick_two[i].y] +                                 2 + dist[pick_two[i].x][pick_two[i].y][meet.x][meet.y];                     if (new_dist < ans)                        ans = new_dist;                     }         }     }void outitdata(){     fout << ans << endl;     fin.close();     fout.close();     }int main(){    initdata();    calc_dist();    solve();    outitdata();    return 0;    }


 

原创粉丝点击