C++——【USACO 3.3.3】——Camelot

来源:互联网 发布:藏头诗软件下载 编辑:程序博客网 时间:2024/06/06 19:12

Camelot
IOI 98

Centuries ago, King Arthur and the Knights of the Round Table used to meet every year on New Year's Day to celebrate their fellowship. In remembrance of these events, we consider a board game for one player, on which one chesspiece king and several knight pieces are placed on squares, no two knights on the same square.

This example board is the standard 8x8 array of squares:


The King can move to any adjacent square from  to  as long as it does not fall off the board:


A Knight can jump from  to , as long as it does not fall off the board:


During the play, the player can place more than one piece in the same square. The board squares are assumed big enough so that a piece is never an obstacle for any other piece to move freely.

The player's goal is to move the pieces so as to gather them all in the same square - in the minimal number of moves. To achieve this, he must move the pieces as prescribed above. Additionally, whenever the king and one or more knights are placed in the same square, the player may choose to move the king and one of the knights together from that point on, as a single knight, up to the final gathering point. Moving the knight together with the king counts as a single move.

Write a program to compute the minimum number of moves the player must perform to produce the gathering. The pieces can gather on any square, of course.

PROGRAM NAME: camelot

INPUT FORMAT

Line 1:Two space-separated integers: R,C, the number of rows and columns on the board. There will be no more than 26 columns and no more than 30 rows.Line 2..end:The input file contains a sequence of space-separated letter/digit pairs, 1 or more per line. The first pair represents the board position of the king; subsequent pairs represent positions of knights. There might be 0 knights or the knights might fill the board. Rows are numbered starting at 1; columns are specified as upper case characters starting with `A'.

SAMPLE INPUT (file camelot.in)

8 8D 4A 3 A 8H 1 H 8

The king is positioned at D4. There are four knights, positioned at A3, A8, H1, and H8.

OUTPUT FORMAT

A single line with the number of moves to aggregate the pieces.

SAMPLE OUTPUT (file camelot.out)

10

SAMPLE OUTPUT ELABORATION

They gather at B5. 
Knight 1: A3 - B5 (1 move) 
Knight 2: A8 - C7 - B5 (2 moves) 
Knight 3: H1 - G3 - F5 - D4 (picking up king) - B5 (4 moves) 
Knight 4: H8 - F7 - D6 - B5 (3 moves) 
1 + 2 + 4 + 3 = 10 moves. 

很久以前,亚瑟王和他的骑士习惯每年元旦去庆祝他们的友谊。为了纪念上述事件, 我们把这些故事看作是一个棋盘游戏。有一个国王和若干个骑士被放置在一个由许多方格 组成的棋盘上,没有两个骑士在同一个方格内。

这个例子是标准的 8*8 棋盘


国王可以移动到任何一个相邻的方格,从下图中黑子位置到下图中白子位置前提是他 不掉出棋盘之外。


一个骑士可以从下图中黑子位置移动到下图中白子位置(走“日”字形) 但前提是他 不掉出棋盘之外。


在游戏中,玩家可在每个方格上放不止一个棋子,假定方格足够大,任何棋子都不会 阻碍到其他棋子正常行动。

玩家的任务就是把所有的棋子移动到同一个方格里——用最小的步数。为了完成这个 任务,他必须按照上面所说的规则去移动棋子。另外,玩家可以选择一个骑士跟国王从他 们两个相遇的那个点开始一起行动,这时他们按照骑士的行动规则行动,其他的单独骑士 则自己一直走到集中点。骑士和国王一起走的时候,只算一个人走的步数。

请计算他们集中在一起的最小步数,而且玩家必须自己找出这个集中点。当然,这些 棋子可以在棋盘的任何地方集合。

输入格式:

第一行: 两个用空格隔开的整数:R,C 分别为棋盘行和列的长。不超过 26 列,40 行。

第二行到结尾: 输入文件包含了一些有空格隔开的字母/数字对,一行有一个或以 上。第一对为国王的位置,接下来是骑士的位置。可能没有骑士,也可能整个棋盘都是骑 士。行从 1 开始,列从大写字母 A 开始。

输出格式:

单独一行表示棋子集中在一个方格的最小步数。

/*ID : mcdonne1PROG : camelotLANG : C++*/#include<cstdio>#include<cstring>#include<cstdlib>#include<queue>using namespace std;struct node{int x,y,step;};int r,c,kx,ky,sum,ans=0x7fffffff;int hx[900],hy[900];int to[27][31][27][31];const int hsx[8]={-2,-2,-1,-1,1,1,2,2};const int hsy[8]={1,-1,2,-2,2,-2,1,-1};inline bool get(int &x,int &y){char c=getchar();while(c<'A'||c>'Z') if((c=getchar())==EOF) return false;x=c-'A'+1;while(c<'0'||c>'9') c=getchar();int i=0;while(c>='0'&&c<='9') i=(i<<3)+(i<<1)+c-48,c=getchar();y=i;return true;}inline void bfs(int x,int y){bool went[27][31];memset(went,false,sizeof(went));queue <node> q;q.push((node){x,y,0});while(!q.empty()){node a=q.front();q.pop();int fx=a.x,fy=a.y;to[x][y][fx][fy]=min(to[x][y][fx][fy],a.step);if(went[fx][fy]) continue;went[fx][fy]=true;for(int i=0;i<8;++i){int dx=fx+hsx[i];int dy=fy+hsy[i];if(dx>0&&dy>0&&dx<=r&&dy<=c) q.push((node){dx,dy,a.step+1});}}}int main(){freopen("camelot.in","r",stdin);freopen("camelot.out","w",stdout);memset(to,127,sizeof(to));scanf("%d%d",&c,&r);get(kx,ky);for(sum=1;get(hx[sum],hy[sum]);++sum) bfs(hx[sum],hy[sum]);if(sum==1){printf("0\n");return 0;}for(int i=-2;i<=2;++i)for(int j=-2;j<=2;++j){int fx=i+kx;int fy=j+ky;if(fx>0&&fy>0&&fx<=r&&fy<=c) bfs(fx,fy);}for(int i=1;i<=r;++i)for(int j=1;j<=c;++j){int dis=0;for(int k=1;k<sum;++k)if(to[hx[k]][hy[k]][i][j]<0x3fffffff) dis+=to[hx[k]][hy[k]][i][j];else{dis=-1;break;}if(dis==-1) continue;for(int p=-2;p<=2;++p)for(int q=-2;q<=2;++q){int fx=kx+p;int fy=ky+q;int king;if(abs(p)==abs(q)) king=abs(p);else if(abs(p)+abs(q)==3) king=2;else king=abs(p)+abs(q);if(fx>0&&fy>0&&fx<=r&&fy<=c)for(int k=1;k<sum;++k)if(to[hx[k]][hy[k]][fx][fy]<0x3fffffff)ans=min(ans,dis-to[hx[k]][hy[k]][i][j]+to[hx[k]][hy[k]][fx][fy]+king+to[fx][fy][i][j]);}}printf("%d\n",ans);return 0;}


原创粉丝点击