zoukankan      html  css  js  c++  java
  • USACO3.3.3Camelot

    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 8
    D 4
    A 3 A 8
    H 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.

    题解:BFS+最优剪枝。自己YY了个想法,就是先用BFS(Floyd会超时。。。)算出所有点对的最短距离,接着枚举集结点,然后计算出所有骑士到集结点的距离和,之后枚举每一个骑士带上国王一起走的方案(可能需要国王走一定的距离),就是这步把我给搞蛋疼了。。。因为我的想法是先让国王走一段距离,然后让骑士带走,这样的话时间复杂度非常高。。。明显又得超时。。。。无奈只好去看解题报告。。。。网上的方法说接国王的点为国王所在位置偏移两个距离就行(即+-2),但貌似无法证明它的正确性,可能是数据不够强大的原因吧。。。所以也能AC。不过这样的做法也可能有它的合理性,让国王尽量少走路,因为骑士每步的偏移量大些,所以尽量让骑士走。提交了几次,第一次是输入有问题,第二次是数组越界,第三次是因为把数组d清成0了,这样也会WA.

    例如这组数据:

    2 26 

    A 1 

    Y 1

    有些集结点骑士根本不能达到,但是还是会进行处理,它会把骑士走的距离计算成0,这样就造成错误了。。。所以必须把d数组全部初始化为一个大值才行。这个错误说明初始化也是非常的重要,一定要看清楚题,再进行相应的初始化,如果不注意的话,到时比赛很有可能就悲剧了。。。

    View Code
      1 /*
      2 ID:spcjv51
      3 PROG:camelot
      4 LANG:C
      5 */
      6 #include<stdio.h>
      7 #include<string.h>
      8 #include<stdlib.h>
      9 #include<math.h>
     10 #define MAXX 35
     11 #define MAXY 35
     12 #define MAXS 10000
     13 int dx[8]= {2,2,1,1,-2,-2,-1,-1};
     14 int dy[8]= {-1,1,-2,2,-1,1,-2,2};
     15 int g[MAXX][MAXY],visit[MAXX][MAXY];
     16 long d[MAXX][MAXY][MAXX][MAXY];
     17 int m,n,kx,ky;
     18 long mins;
     19 long max(long a,long b)
     20 {
     21     return a>b?a:b;
     22 }
     23 long min(long a,long b)
     24 {
     25     return a<b?a:b;
     26 }
     27 void shortpath(int sx,int sy)
     28 {
     29     long q[2][1000];
     30     long head,tail,i,tx,ty;
     31     memset(q,0,sizeof(q));
     32     memset(visit,0,sizeof(visit));
     33     head=0;
     34     tail=1;
     35     q[0][tail]=sx;
     36     q[1][tail]=sy;
     37     visit[sx][sy]=1;
     38     d[sx][sy][sx][sy]=0;
     39     while(head<tail)
     40     {
     41         head++;
     42         tx=q[0][head];
     43         ty=q[1][head];
     44         for(i=0; i<8; i++)
     45             if(tx+dx[i]>=1&&tx+dx[i]<=n&&ty+dy[i]>=1&&ty+dy[i]<=m&&!visit[tx+dx[i]][ty+dy[i]])
     46             {
     47                 tail++;
     48                 q[0][tail]=tx+dx[i];
     49                 q[1][tail]=ty+dy[i];
     50                 visit[tx+dx[i]][ty+dy[i]]=1;
     51                 d[sx][sy][q[0][tail]][q[1][tail]]=d[sx][sy][tx][ty]+1;
     52             }
     53     }
     54 }
     55 long solve(int x,int y)
     56 {
     57     long i,j,sum,tt,tx,ty;
     58     sum=0;
     59     for(i=1;i<=n;i++)
     60     for(j=1;j<=m;j++)
     61     if(g[i][j])
     62     {
     63         sum+=d[i][j][x][y];
     64         if(sum>mins) return MAXS;
     65     }
     66     tt=sum+max(abs(x-kx),abs(y-ky));
     67     for(tx=max(1,kx-2);tx<=min(n,kx+2);tx++)
     68     for(ty=max(1,ky-2);ty<=min(m,ky+2);ty++)
     69     for(i=1;i<=n;i++)
     70     for(j=1;j<=m;j++)
     71     if(g[i][j])
     72     tt=min(tt,sum+max(abs(tx-kx),abs(ty-ky))+d[i][j][tx][ty]+d[tx][ty][x][y]-d[i][j][x][y]);
     73     //printf("%d\n",tt);
     74     return tt;
     75 }
     76 int main(void)
     77 {
     78     freopen("camelot.in","r",stdin);
     79     freopen("camelot.out","w",stdout);
     80     int i,j,t;
     81     long ans,ts;
     82     char ch[10];
     83     scanf("%d%d",&n,&m);
     84     scanf("%s%d",ch,&t);
     85     kx=t;
     86     ky=ch[0]-'A'+1;
     87     memset(g,0,sizeof(g));
     88     memset(d,1,sizeof(d));
     89     while(scanf("%s%d",ch,&t)!=EOF)
     90     {
     91         g[t][ch[0]-'A'+1]=1;
     92         getchar();
     93     }
     94     for(i=1; i<=n; i++)
     95         for(j=1; j<=m; j++)
     96             shortpath(i,j);
     97     ans=MAXS;
     98     mins=MAXS;
     99     for(i=1; i<=n; i++)
    100         for(j=1; j<=m; j++)
    101         {
    102               ts=solve(i,j);
    103               if(ts<ans)
    104               {
    105                   ans=ts;
    106                   mins=ans;
    107               }
    108         }
    109     printf("%ld\n",ans);
    110     return 0;
    111 }
  • 相关阅读:
    排名第一、第二的OCR软件
    补码输出
    枚举 与 枚举的应用
    动态构造结构体数组
    c 冒泡排序
    strcpy
    typedef用法
    C 结构体小结
    int 占一个机器字长
    SQL Server创建视图——视图的作用
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/2960466.html
Copyright © 2011-2022 走看看