您的位置:首页 > 其它

POJ 1178 Camelot (floyed算法)

2010-08-10 21:40 309 查看
本题没有读懂题目,想偏后导致各种不顺。我理解的是每个骑士间和国王都可以同步的移动。原来是一次只能移动一个人,求总步数最小。于是就简单多了。开始想歪后,在论坛找到一种说法:预处理+纯暴力。原文说“枚举64个终点 * 枚举64个接国王点 * 枚举64只来接的骑士 总复杂度O(64*64*64)”。这时候我才明白原来题目意思是要求求所有步数的最小值。Google题目的翻译。
这里是题目链接。题目大意:棋盘上有1个国王和若干个骑士,要把国王和每个骑士移动到同一个格子内,问需要移动的最小步数是多少。如果国王和骑士走到同一个格子里,可以由骑士带着国王一起移动。参考来源
题目转化为2张图,国王为点(实际上每一个格子都是点),每一个点到采用国王移动规则移到的另一个点为一条权值为1的边。Floyd算法可以算出每两点之间的最短路径,也就是国王从一点移动到另一点的最短步数。另外一张骑士的图同理。
于是算法转化为以上第一段说的三个枚举。我的代码如下:
1: #include <iostream>


2: #include <string>


3: #include <algorithm>


4: 


5: using namespace std;


6: const int MAX_INT = (1<<15);


7: const int SQUARE_SIZE = 64;


8: 


9: int kings[SQUARE_SIZE][SQUARE_SIZE];


10: int knights[SQUARE_SIZE][SQUARE_SIZE];


11: int people[SQUARE_SIZE];


12: const int kingsStep[8][2] = {{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}};


13: const int knightsStep[8][2] = {{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};


14: 


15: void initGraph()


16: {


17:     for (int i=0; i<SQUARE_SIZE; i++)


18:     {


19:         for (int j=0; j<SQUARE_SIZE; j++)


20:             kings[i][j] = knights[i][j] = (i==j ? 0:MAX_INT);


21:     }


22:     for (int i=0; i<SQUARE_SIZE; i++)


23:     {


24:         int fromX=i/8, fromY=i%8;


25:         int toX, toY;


26:         for (int j=0; j<8; j++)


27:         {


28:             toX=fromX+kingsStep[j][0];


29:             toY=fromY+kingsStep[j][1];


30:             if (toX>=0 && toX<8 && toY>=0 && toY<8)


31:                 kings[i][8*toX+toY] = 1;


32:


33:             toX=fromX+knightsStep[j][0];


34:             toY=fromY+knightsStep[j][1];


35:             if (toX>=0 && toX<8 && toY>=0 && toY<8)


36:                 knights[i][8*toX+toY] = 1;


37:         }


38:     }


39: }


40: 


41: void floyd()


42: {


43:     for (int k=0; k<SQUARE_SIZE; k++)


44:     {


45:         for (int i=0; i<SQUARE_SIZE; i++)


46:         {


47:             for (int j=0; j<SQUARE_SIZE; j++)


48:             {


49:                 kings[i][j] = min(kings[i][j], kings[i][k]+kings[k][j]);


50:                 knights[i][j] = min(knights[i][j], knights[i][k]+knights[k][j]);


51:             }


52:         }


53:     }


54: }


55: 


56: int main()


57: {


58:     initGraph();


59:     floyd();


60:     string s;


61:     cin >> s;


62:     int count=s.size()/2;


63:     for (size_t i=0, j=0; i<s.size(); i=i+2,j++)


64:         people[j] =(s[i]-'A')+(s[i+1]-'1')*8;


65:


66:     int res=MAX_INT;


67:     int sum=0;


68:     for (int end=0; end<SQUARE_SIZE; end++)


69:     {


70:         sum = 0;


71:         for (int j=1; j<count; j++)


72:             sum += knights[people[j]][end];


73:         if (sum>res)    continue;


74:


75:         for (int meet=0; meet<SQUARE_SIZE; meet++)


76:         {


77:             int step1=kings[people[0]][meet];


78:             int step2=MAX_INT;


79:             for (int k=1; k<count; k++)


80:                 step2 = min(step2, knights[people[k]][meet]+knights[meet][end]-knights[people[k]][end]);


81:             res = min(res, sum+step1+step2);


82:         }


83:     }


84:     cout << res << endl;


85:     s.clear();


86:     return 0;


87: }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: