zoukankan      html  css  js  c++  java
  • POJ 1178 预处理+枚举+floyd

    Camelot
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 2839   Accepted: 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

     

    POJ 1178解题思路:

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

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

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

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

    ans=min(ans[i]);

     

     

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cstdlib>
      6 using namespace std;
      7 const int inf=0x3fffffff;
      8 int next_king[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
      9 int next_knight[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};
     10 int minpath_king[64][64],minpath_knight[64][64];
     11 int top;
     12 char str[300];
     13 struct point
     14 {
     15     int x,y,pp;
     16 };
     17 point p[100];
     18 bool judge(int xx,int yy)
     19 {
     20     if(xx>=0&&xx<8&&yy>=0&&yy<8) return 1;
     21     return 0;
     22 }
     23 void init()
     24 {
     25     for(int i=0;i<64;i++)
     26     {
     27         for(int j=0;j<64;j++)
     28         {
     29             minpath_king[i][j]=inf;
     30             minpath_knight[i][j]=inf;
     31         }
     32         minpath_king[i][i]=0;
     33         minpath_knight[i][i]=0;
     34         int gx=i/8,gy=i%8;
     35         int tx,ty;
     36         for(int j=0;j<8;j++)
     37         {
     38             tx=gx+next_king[j][0];
     39             ty=gy+next_king[j][1];
     40             if(judge(tx,ty)){
     41                 minpath_king[i][tx*8+ty]=1;
     42             }
     43             tx=gx+next_knight[j][0];
     44             ty=gy+next_knight[j][1];
     45             if(judge(tx,ty)){
     46                 minpath_knight[i][tx*8+ty]=1;
     47             }
     48         }
     49     }
     50 }
     51 void floyd()
     52 {
     53     for(int k=0;k<64;k++)
     54         for(int i=0;i<64;i++)
     55           for(int  j=0;j<64;j++)
     56     {
     57         minpath_king[i][j]=min(minpath_king[i][j],minpath_king[i][k]+minpath_king[k][j]);
     58         minpath_knight[i][j]=min(minpath_knight[i][j],minpath_knight[i][k]+minpath_knight[k][j]);
     59     }
     60 }
     61 int slove()
     62 {
     63     int gx,gy,gp;
     64     int ans=inf,sum=0;
     65     for(int i=0;i<64;i++)//枚举最后的点
     66     {
     67         sum=0;
     68       for(int j=1;j<top;j++)
     69       {
     70           sum+=minpath_knight[i][p[j].pp];
     71       }
     72       for(int j=1;j<top;j++)//枚举携带了国王的骑士
     73         for(int k=0;k<64;k++)//枚举骑士与国王的相遇点
     74         {
     75             sum+=minpath_knight[p[j].pp][k]+minpath_knight[k][i]+minpath_king[p[0].pp][k];
     76             sum-=minpath_knight[i][p[j].pp];
     77             if(sum<ans) ans=sum;
     78             sum-=minpath_knight[p[j].pp][k]+minpath_knight[k][i]+minpath_king[p[0].pp][k];
     79             sum+=minpath_knight[i][p[j].pp];
     80         }
     81     }
     82     return ans;
     83 }
     84 int main()
     85 {
     86    // freopen("in.txt","r",stdin);
     87     scanf("%s",str);char s1,s2;
     88     int l=strlen(str);top=0;
     89     for(int i=0;i<l;i+=2)
     90     {
     91         s1=str[i];s2=str[i+1];
     92         p[top].x=s1-'A';
     93         p[top].y=s2-'1';
     94         p[top].pp=p[top].x*8+p[top].y;
     95         top++;
     96     }
     97     init();floyd();
     98     int ans=slove();
     99     printf("%d
    ",ans);
    100     return 0;
    101 }

     

     

  • 相关阅读:
    python內建模块之datetime
    python实现两个经纬度点之间的距离和方位角
    Python实现DBScan
    关于sru源码class Model的parameters
    pytorch之LSTM
    pytorch对可变长度序列的处理
    pytorch函数之torch.normal()
    PyTorch学习系列(九)——参数_初始化
    ubuntu16.04系统搜狗输入法的安装
    Scala 匿名函数
  • 原文地址:https://www.cnblogs.com/codeyuan/p/4271394.html
Copyright © 2011-2022 走看看