您的位置:首页 > 其它

POJ 1178 预处理+枚举+floyd

2015-02-04 00:19 351 查看
Camelot

Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 2839Accepted: 1334
Description

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 king and several knight pieces are placed at random on distinct squares.
The Board is an 8x8 array of squares. The King can move to any
adjacent square, as shown in Figure 2, as long as it does not fall off
the board. A Knight can jump as shown in Figure 3, 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 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 smallest possible 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
henceforth, 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.

Input

Your
program is to read from standard input. The input contains the initial
board configuration, encoded as a character string. The string contains a
sequence of up to 64 distinct board positions, being the first one the
position of the king and the remaining ones those of the knights. Each
position is a letter-digit pair. The letter indicates the horizontal
board coordinate, the digit indicates the vertical board coordinate.

0 <= number of knights <= 63
Output

Your
program is to write to standard output. The output must contain a
single line with an integer indicating the minimum number of moves the
player must perform to produce the gathering.
Sample Input

D4A3A8H1H8

Sample Output

10

Source

IOI 1998

POJ 1178解题思路:

1.枚举最后的相遇点、与国王相遇的骑士以及国王与骑士的相遇点,复杂度O(64*n*64);

2.首先预处理一下,把骑士走时任意两点间的最短路,国王走时任意两点间的最短路都算出来;

3.首先枚举一个目的地,计算出所有的骑士到目的地的距离sum,然后再枚举一个骑士为携带国王的骑士,最后枚举骑士与国王的相遇点。每一次枚举的答案为:

ans[i]=sum+相应骑士从初始点到相遇点的距离+骑士从相遇点到终点的距离+国王从初始点到相遇点的距离-相应骑士从初始点到终点的距离;

ans=min(ans[i]);

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
const int inf=0x3fffffff;
int next_king[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int next_knight[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};
int minpath_king[64][64],minpath_knight[64][64];
int top;
char str[300];
struct point
{
int x,y,pp;
};
point p[100];
bool judge(int xx,int yy)
{
if(xx>=0&&xx<8&&yy>=0&&yy<8) return 1;
return 0;
}
void init()
{
for(int i=0;i<64;i++)
{
for(int j=0;j<64;j++)
{
minpath_king[i][j]=inf;
minpath_knight[i][j]=inf;
}
minpath_king[i][i]=0;
minpath_knight[i][i]=0;
int gx=i/8,gy=i%8;
int tx,ty;
for(int j=0;j<8;j++)
{
tx=gx+next_king[j][0];
ty=gy+next_king[j][1];
if(judge(tx,ty)){
minpath_king[i][tx*8+ty]=1;
}
tx=gx+next_knight[j][0];
ty=gy+next_knight[j][1];
if(judge(tx,ty)){
minpath_knight[i][tx*8+ty]=1;
}
}
}
}
void floyd()
{
for(int k=0;k<64;k++)
for(int i=0;i<64;i++)
for(int  j=0;j<64;j++)
{
minpath_king[i][j]=min(minpath_king[i][j],minpath_king[i][k]+minpath_king[k][j]);
minpath_knight[i][j]=min(minpath_knight[i][j],minpath_knight[i][k]+minpath_knight[k][j]);
}
}
int slove()
{
int gx,gy,gp;
int ans=inf,sum=0;
for(int i=0;i<64;i++)//枚举最后的点
{
sum=0;
for(int j=1;j<top;j++)
{
sum+=minpath_knight[i][p[j].pp];
}
for(int j=1;j<top;j++)//枚举携带了国王的骑士
for(int k=0;k<64;k++)//枚举骑士与国王的相遇点
{
sum+=minpath_knight[p[j].pp][k]+minpath_knight[k][i]+minpath_king[p[0].pp][k];
sum-=minpath_knight[i][p[j].pp];
if(sum<ans) ans=sum;
sum-=minpath_knight[p[j].pp][k]+minpath_knight[k][i]+minpath_king[p[0].pp][k];
sum+=minpath_knight[i][p[j].pp];
}
}
return ans;
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%s",str);char s1,s2;
int l=strlen(str);top=0;
for(int i=0;i<l;i+=2)
{
s1=str[i];s2=str[i+1];
p[top].x=s1-'A';
p[top].y=s2-'1';
p[top].pp=p[top].x*8+p[top].y;
top++;
}
init();floyd();
int ans=slove();
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: