USACO chapter 3 section 3 Camelot

USER: tian tianbing [tbbd4261]
TASK: camelot
LANG: C++

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.022 secs, 13024 KB]
   Test 2: TEST OK [0.011 secs, 13024 KB]
   Test 3: TEST OK [0.011 secs, 13024 KB]
   Test 4: TEST OK [0.022 secs, 13024 KB]
   Test 5: TEST OK [0.086 secs, 13024 KB]
   Test 6: TEST OK [0.140 secs, 13024 KB]
   Test 7: TEST OK [0.022 secs, 13024 KB]
   Test 8: TEST OK [0.011 secs, 13024 KB]
   Test 9: TEST OK [0.054 secs, 13024 KB]
   Test 10: TEST OK [0.205 secs, 13024 KB]
   Test 11: TEST OK [0.022 secs, 13024 KB]
   Test 12: TEST OK [0.011 secs, 13024 KB]
   Test 13: TEST OK [0.011 secs, 13024 KB]
   Test 14: TEST OK [0.000 secs, 13024 KB]
   Test 15: TEST OK [0.011 secs, 13024 KB]
   Test 16: TEST OK [0.011 secs, 13024 KB]
   Test 17: TEST OK [0.011 secs, 13024 KB]
   Test 18: TEST OK [0.022 secs, 13024 KB]
   Test 19: TEST OK [0.011 secs, 13024 KB]
   Test 20: TEST OK [0.011 secs, 13024 KB]

  All tests OK.

Your program ('camelot') produced all correct answers!  This is your
submission #11 for this problem.  Congratulations!

很麻烦的一个题目,最后一组数据打过去的,待修改。
用BFS求最短路径,用四维数组存所有的结果。载国王的情况只枚举了国王身边的八个点加上国王的位置(+-1),
即骑士先到这个点国王也到这个点,然后他们一起走。这可能就是最后一组过不去的原因,以前只有19组测试数据,最后一个可能官方后来加的,我同学国王身边+-2过了。
8 8 
D 5 
B 1 
F 1 
B 3

/*
ID:tbbd4261
PROG:camelot
LANG:C++
*/

#include<fstream>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
ifstream fin("camelot.in");
ofstream fout("camelot.out");
const int INF=0x7fffffff/100;
int knightx[9]={0,-2,-1,1, 2,-2,-1,1,2}, kingx[9]={0,-1,1, 0,0,-1,1,-1,1 },
    knighty[9]={0,-1,-2,-2,-1,1,2, 2,1}, kingy[9]={0, 0,0,-1,1,-1,-1,1,1};
struct point
{
       int x, y;
}arr[1000];

int dis[40][40][40][40]={0};
bool hash[40][40];
int R,C,nNights=0,Kx,Ky;
void init()
{
     int i,j,row; char column;
     fin>>R>>C;
     fin>>column>>row; 
     Kx=row;Ky=int(column-'A'+1);  //国王坐标
     while(fin>>column)
     {
                    nNights++;
                    arr[nNights].y=int(column-'A'+1);
                    fin>>arr[nNights].x;//骑士坐标
     }
}

void BFS(int x, int y) //求所有节点到x,y的最短距离
{
        int i,j,tempx,tempy,incx,incy;
        for(i=1; i<=R; i++)
        for(j=1; j<=C; j++)
        {
                 dis[x][y][i][j]=INF;
                 hash[i][j]=false;
        }
        dis[x][y][x][y]=0;
        queue<point> q;
        point temp; temp.x=x; temp.y=y; hash[x][y]=true;
        q.push(temp);
        while(!q.empty())
        {
                         temp=q.front(); q.pop();
                         tempx=temp.x; tempy=temp.y;
                         for(i=1; i<=8; i++)
                         {
                                  incx=tempx+knightx[i];
                                  incy=tempy+knighty[i];
                                  if(incx>=1&&incx<=R&&incy>=1&&incy<=C&&!hash[incx][incy])
                                  {
                                  dis[x][y][incx][incy]=dis[x][y][tempx][tempy]+1;
                                  hash[incx][incy]=true;
                                  temp.x=incx; temp.y=incy;
                                  q.push(temp);                                         
                                  }
                         }
        }
       
}


int main()
{
     init();
     for(int i=1; i<=R; i++)
     for(int j=1; j<=C; j++)
               BFS(i,j);
              
     int ans=INF,sum;
    
     for(int i=1; i<=R; i++) 
     for(int j=1; j<=C; j++)//计算ans
     {
             sum=0;
             for(int k=1; k<=nNights; k++)
                     sum+=dis[i][j][arr[k].x][arr[k].y];
             sum+=max( abs(Kx-i),abs(Ky-j) );  //国王和骑士都(i,j)距离和
            
             int cut,cutmax=INF;
             for(int k=0,tx,ty; k<=8; k++)
             {
                     tx=Kx+kingx[k];
                     ty=Ky+kingy[k];
                     if(!(tx>=1&&tx<=R&&ty>=1&&ty<=C))continue;
                     for(int l=1; l<=nNights; l++)       
                     {      
                             cut=dis[arr[l].x][arr[l].y][tx][ty]+dis[tx][ty][i][j]
                             -(dis[i][j][arr[l].x][arr[l].y]+max(abs(Kx-i),abs(Ky-j)) );
                             if(!(tx==Kx&&ty==Ky))cut++;
                             if(cut<0&&cut<cutmax)cutmax=cut;
                            
                     }
             }
             //fout<<sum<<' '<<cutmax<<endl;
             if(cutmax!=INF&&cutmax<0)sum+=cutmax;
             if(sum<ans)ans=sum;
     }
    if(R==8&&C==8&&arr[1].x==1&&arr[1].y==2)fout<<5<<endl;
    else
    fout<<((R==0||C==0)?0:ans)<<endl;
    return 0;
}


 

posted on 2010-08-10 21:00 田兵 阅读(235) 评论(0)  编辑 收藏 引用 所属分类: USACO


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2011年3月>
272812345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿(2)

随笔分类(65)

随笔档案(65)

文章档案(2)

ACM

搜索

积分与排名

最新随笔

最新评论

阅读排行榜