poj1178 floyd+枚举

http://poj.org/problem?id=1178

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
/**
poj 1178  floyd+枚举
题目大意:在一个8*8的棋盘里有一个国王和一些骑士,我们需要把他们送到同一顶点上去,骑士和国王的行动方式如图所示。国王可以选择一名骑士作为坐骑,上马后相当和该骑士
          一起行动(相当于一个骑士),同一位置可以同时有多个骑士和国王,问最少走的步数
解题思路:把8*8棋盘变成0~63的数,Floyd求出任意两点之间的最短路径。8*8枚举即可。枚举终点,骑士上马点,国王上哪个骑士,最终负责度O(64^4)。
*/
#include <string.h>
#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;

char s[105];
int cx[8][2]= {{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};
int dx[8][2]= {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int a[65][65],b[65][65],rking[65],king;

bool judge(int i,int j)
{
    if(i>=0&&i<8&&j>=0&&j<8)
        return true;
    return false;
}

void init()
{
    for(int i=0; i<64; i++)
    {
        for(int j=0; j<64; j++)
        {
            if(i==j)
                a[i][j]=b[i][j]=0;
            else
                a[i][j]=b[i][j]=999;
        }
    }
    for(int i=0; i<8; i++)
    {
        for(int j=0; j<8; j++)
        {
            for(int k=0; k<8; k++)
            {
                int x=i+cx[k][0];
                int y=j+cx[k][1];
                int xx=i+dx[k][0];
                int yy=j+dx[k][1];
                if(judge(x,y))
                {
                    a[i+j*8][x+y*8]=1;
                }
                if(judge(xx,yy))
                {
                     b[i+j*8][xx+yy*8]=1;
                }
            }
        }
    }
    for(int k=0; k<64; k++)
    {
        for(int i=0; i<64; i++)
        {
            for(int j=0; j<64; j++)
            {
                a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
                b[i][j]=min(b[i][j],b[i][k]+b[k][j]);
            }
        }
    }
}
int main()
{
    init();
    while(~scanf("%s",s))
    {
        int n=strlen(s);
        king=s[0]-'A'+(s[1]-'1')*8;
        int cnt=0;
        for(int i=2; i<n; i+=2)
        {
            int x=s[i+1]-'1';
            int y=s[i]-'A';
            rking[cnt++]=x*8+y;
        }
        int ans=9999999;
        for(int i=0;i<64;i++)///终点
        {
            for(int j=0;j<64;j++)///国王上马点
            {
                for(int k=0;k<cnt;k++)///国王所上的骑士
                {
                    int sum=0;
                    for(int l=0;l<cnt;l++)
                    {
                        if(l==k)continue;
                        sum+=a[rking[l]][i];
                    }
                    sum+=b[king][j]+a[rking[k]][j]+a[j][i];
                    ans=min(ans,sum);
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

时间: 2024-10-28 00:58:21

poj1178 floyd+枚举的相关文章

USACO cowtour Floyd + 枚举

给出来的数据量还是可以的.题意:有若干个牧场,至少有两个不连通,一个牧场的直径就是牧场中最远的两个牧区的距离.要求找出几个牧场中最短的直径,就是找一条路径连接几个牧区,使这个直径最终最小. 基本方法,把整个图根据输入划分成几个不连通的牧区,然后求出每个牧区的直径(即每个连通块中的最长路径),然后枚举两个不在同一牧区的点,设blocks[i]记录第i个节点所在连通块的直径,那么result = min(blocks[i] + dis(i, j) + blocks[j]),可以用并查级判断两个点是否

【基础练习】【floyd+枚举】codevs1020 孪生蜘蛛题解

题目描述 Description 在G城保卫战中,超级孪生蜘蛛Phantom001和Phantom002作为第三层防卫被派往守护内城南端一带极为隐秘的通道. 根据防护中心的消息,敌方已经有一只特种飞蛾避过第二层防卫,直逼内城南端通道入口.但优秀的蜘蛛已经在每个通道内埋下了坚固的大网,无论飞蛾进入哪个通道,他只有死路一条!(因为他是无法挣脱超级蛛网的) 现在,001和002分别驻扎在某两个通道内.各通道通过内线相通,通过每条内线需要一定的时间.当特种飞蛾被困某处,001或002会迅速赶来把它结果掉

Stockbroker Grapevine (poj 1125 floyd + 枚举)

Language: Default Stockbroker Grapevine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 27445   Accepted: 15211 Description Stockbrokers are known to overreact to rumours. You have been contracted to develop a method of spreading disinfo

poj 1161 Floyd+枚举

题意是: 给出n个点,围成m个区域.从区域到另一个区域间需穿过至少一条边(若两区域相邻)——边连接着两点. 给出这么一幅图,并给出一些点,问从这些点到同一个区域的穿过边数最小值. 解题思路如下: 将区域按1~m编号,d[i][j]表示第 i 个区域到第 j 个区域的最短距离,跑一遍Floye算法O(m^3)后,枚举选择的区域,找出其中穿过边数最小值即可. 建图:题目对于每个区域的描述方式为以顺时针方向给出围成区域的点.由此可知区域由哪些边组成.易知,每条边能且只能令两个区域相邻,则用二维数组记录

IOI 2000 Walls Floyd+枚举

Walls   PROBLEM In a country, great walls have been built in such a way that every great wall connects exactly two towns. The great walls do not cross each other. Thus, the country is divided into such regions that to move from one region to another,

bzoj 1491: [NOI2007]社交网络

Description 在社交网络(socialnetwork)的研究中,我们常常使用图论概念去解释一些社会现象.不妨看这样的一个问题. 在一个社交圈子里有n个人,人与人之间有不同程度的关系.我们将这个关系网络对应到一个n个结点的无向图上, 两个不同的人若互相认识,则在他们对应的结点之间连接一条无向边,并附上一个正数权值c,c越小,表示两个人 之间的关系越密切.我们可以用对应结点之间的最短路长度来衡量两个人s和t之间的关系密切程度,注意到最短路 径上的其他结点为s和t的联系提供了某种便利,即这些

[bzoj2208][Jsoi2010]连通数

来自FallDream的博客,未经允许,请勿转载,谢谢. n<=2000 bitset优化floyd , 枚举k,枚举i,如果i能到k,那么i的bitset直接或上k的.复杂度$O(\frac{n^{3}}{32})$ #include<iostream> #include<cstdio> #include<bitset> #define MN 2000 using namespace std; inline int read() { int x = 0 , f

CodeVS 1020孪生蜘蛛

虽然最近最短路写的挺熟练的,但这道题还是坑了我两个小时..   题目大意:在一个无向图里找两个结点使在除了这两个结点以外的任意一个结点到这两个结点的权值最小.(距离为出发结点到两     个结点的最小权值).   算法:Floyd+枚举(SPFA蜜汁TLE..)      首先这道题读了好几遍都不知道它要求什么(题意好迷啊..),一直不明白什么叫最坏情况下的最优解,按自己的理解打了spfa,交    上去全wa..于是按着wa的数据手动画了个图,然后跟着答案去推,才发现是求一波最短路再枚举两个点

套题T3

秋实大哥与线段树 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status “学习本无底,前进莫徬徨.” 秋实大哥对一旁玩手机的学弟说道. 秋实大哥是一个爱学习的人,今天他刚刚学习了线段树这个数据结构. 为了检验自己的掌握程度,秋实大哥给自己出了一个题,同时邀请大家一起来作. 秋实大哥的题目要求你维护一个序列,支持两种操作:一种是修改某一个元素的值:一种是询问