zoukankan      html  css  js  c++  java
  • USACO Training3.3亚瑟王的宫殿【搜索】By cellur925

    题目传送门

    因为太蒟了,所以参考了dalao@zbtrs ==    对此表示感谢并侵删。

    看起来我们就知道这是搜索题。

    最后的情况分两种:有骑士背国王/国王自食其力走到集合点。

    首先,我们不知道大家最后集合在哪里,所以可以枚举一下这个点。

    其次,我们不知道是哪个骑士背,所以再枚举一下。

    再次,我们不知道在哪里接国王,所以再枚举一下这个点。

    这是思路的大体框架。然后在更新答案时,我们需要求出在棋盘上一个点到另一点的最短距离。然后因为我们可以等效的认为这是一个无向无环图,所以直接用bfs顺便跑出最短距离就行了==。

    细节:赋初值。dis数组和ans都要赋成正无穷。因为我们在寻求一个最小值。

    优化:最优性剪枝(代码中)

    Code

     1 /*
     2 ID:cellur_2
     3 TASK:camelot
     4 LANG:C++
     5 */
     6 #include<cstdio>
     7 #include<algorithm>
     8 #include<queue>
     9 #include<cstring>
    10 
    11 using namespace std;
    12 const int inf=0x3f3f3f;
    13 
    14 int n,m,cnt,ans=inf;
    15 char ch[5];
    16 bool vis[41][27];
    17 int dx[10]={0,-2,-1,1,2,2,1,-1,-2};
    18 int dy[10]={0,1,2,2,1,-1,-2,-2,-1};
    19 int dis[41][27][41][27];
    20 int kingx,kingy;
    21 struct point{
    22     int x,y;
    23 }knight[2000];
    24 
    25 bool valid(int x,int y)
    26 {
    27     if(x>=1&&x<=n&&y>=1&y<=m) return 1;
    28     return 0;
    29 }
    30 
    31 void bfs(int x,int y)
    32 {
    33     queue<pair<int,int> >q;
    34     q.push(make_pair(x,y));
    35     memset(vis,0,sizeof(vis));
    36     vis[x][y]=1;
    37     dis[x][y][x][y]=0;
    38     while(!q.empty())
    39     {
    40         int xx=q.front().first;
    41         int yy=q.front().second;
    42         q.pop();
    43         int step=dis[x][y][xx][yy];
    44         for(int i=1;i<=8;i++)
    45         {
    46             int rx=xx+dx[i];
    47             int ry=yy+dy[i];
    48             if(valid(rx,ry)&&!vis[rx][ry])
    49             {
    50                 dis[x][y][rx][ry]=step+1;
    51                 q.push(make_pair(rx,ry));
    52                 vis[rx][ry]=1;
    53             }
    54         }
    55     }
    56 }
    57 
    58 int main()
    59 {
    60     freopen("camelot.in","r",stdin);
    61     freopen("camelot.out","w",stdout);
    62     scanf("%d%d",&n,&m);
    63     scanf("%s",ch+1);kingy=(int)ch[1]-'A'+1;
    64     scanf("%d",&kingx);kingx=n-kingx+1;
    65     while(scanf("%s",ch+1)!=EOF)
    66     {
    67         knight[++cnt].y=(int)ch[1]-'A'+1;
    68         scanf("%d",&knight[cnt].x);
    69         knight[cnt].x=n-knight[cnt].x+1;
    70     }
    71     for(int i=1;i<=n;i++)
    72         for(int j=1;j<=m;j++)
    73             for(int a=1;a<=n;a++)
    74                 for(int b=1;b<=m;b++)
    75                     dis[i][j][a][b]=inf;
    76     for(int i=1;i<=n;i++)
    77         for(int j=1;j<=m;j++)
    78             bfs(i,j);
    79     for(int i=1;i<=n;i++)
    80         for(int j=1;j<=m;j++)
    81         {
    82             int tmp=0;
    83             for(int k=1;k<=cnt;k++)
    84                 tmp+=dis[knight[k].x][knight[k].y][i][j];
    85             ans=min(ans,tmp+max(abs(kingx-i),abs(kingy-j)));
    86             //先考虑国王不被帮助运送的情况 
    87             for(int k=1;k<=cnt;k++)
    88             {//需要重开变量,不能偷懒用tmp直接减,否则会一直减
    89                 int tmpp=tmp-dis[knight[k].x][knight[k].y][i][j];
    90                 if(tmp>=ans) continue;//最优性剪枝 
    91                 for(int l=1;l<=n;l++)
    92                     for(int r=1;r<=m;r++)
    93                         ans=min(ans,tmpp+dis[knight[k].x][knight[k].y][l][r]+dis[l][r][i][j]+max(abs(kingx-l),abs(kingy-r)));
    94             }
    95         }
    96     printf("%d
    ",ans);
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    emberjs 循环中设置model的不同属性值
    FUTURE .get 异常抛出会如何提示
    cpu ,鲲鹏,x86,主频,门电路,目录
    复制两个类的相同属性
    【深入Java虚拟机(1)】:Java内存区域与内存溢出
    RPC web service
    webservice
    django中配置Pymsql
    定义函数和调用函数的方式,函数形参和实参的介绍
    python名称空间与作用域
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9636258.html
Copyright © 2011-2022 走看看