POJ 1178 Camelot 最短路 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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章