zoukankan      html  css  js  c++  java
  • 洛谷-3930(我在洛谷上也写了题解)

    https://www.luogu.org/problem/show?pid=P3930

    这道题,其实完全不需要你去你用什么高级算法,其实需要你的,是耐心地爆搜,像2015年斗地主一样了,但有一个坑,我没注意到,于是得了80分,那就是:因为进攻方是骑士,所以进攻方是不可能吃到骑士的。大体呢就是先把开始点和结束点记录下来,然后开结构体,结构体里面要有它当时棋盘的状态和进攻方所在位置,然后把那些敌方的记录下来,每次往8个方向枚举,符合条件(就是没跳出棋盘,不会被地方吃到) 。因为宽搜要快一些,所以我们用宽搜,要开一个队列,搜到了第一个吃到国王的就跳出来,返回步数。搜完后还不行,就返回1.

    注意:如果跳到了敌方的一个棋子上,就要把那颗棋子去掉!
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cmath>
    using namespace std;
    const int inf=0x3f3f3f3f;
    struct wo{
        char b[60][60];//棋盘状态
        int x,y;//
    };
    queue<wo>p;
    char a[60][60];
    int vis[60][60];//记录有多少颗敌方棋子能吃到自己 
    int step[60][60];//记录到达当前点至少要用多少步 
    int n;
    int dx[8]={1,1,-1,-1,2,2,-2,-2};//八个方向 
    int dy[8]={2,-2,2,-2,1,-1,1,-1};//八个方向 
    int startx,starty,endx,endy;//开始点和结束点 
    int judge(int x,int y){
        if(x<=0||x>n)return 0;
        if(y<=0||y>n)return 0;
        if(vis[x][y])return 0;
        return 1;
    }
    void queen(int x,int y){//皇后攻击范围内的 
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if((i==x)||(j==y)||((i+j)==(x+y))||((i-j)==(x-y)))//横坐标一样,竖坐标一样,或者在同一条斜线上 
                vis[i][j]++;//能攻击到这一点 
            }
        }
        vis[x][y]--;//自己攻击不了自己! 
    }
    void castle(int x,int y){//城堡攻击范围 
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if((i==x)||(j==y))//横坐标一样或竖坐标一样 
                vis[i][j]++;//能攻击到这一点 
            }
        }
        vis[x][y]--;//自己攻击不了自己! 
    }
    void B(int x,int y){//主教攻击范围 
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(((i+j)==(x+y))||((i-j)==(x-y)))//在同一条斜线上 
                vis[i][j]++;//就吃得到 
            }
        }
        vis[x][y]--;//自己攻击不了自己! 
    }
    void knight(int x,int y){ 
        for(int i=0;i<8;i++){
            if(judge(x+dx[i],y+dy[i])){//在骑士的8个方向上,且在棋盘上 
                vis[x+dx[i]][y+dy[i]]++;//就吃得到
            }
        }
        //因为攻击方也是骑士,所以攻击方吃不了 
    }
    void solider(int x,int y){
        vis[x+1][y-1]++;vis[x+1][y+1]++;//士兵只能攻击到两个点 
    }
    void king(int x,int y){
         for(int i=1;i<=n;i++){
             for(int j=1;j<=n;j++){
                 if(abs(x-i)<=1&&abs(y-j)<=1)vis[i][j]++;//国王的8个方向内能被吃到 
             }
         }
         vis[x][y]=0; //自己攻击不了自己!    
    }
    void me(int x,int y){
        startx=x,starty=y;//记录开始坐标 
    }
    int solve(){
        while(p.size())p.pop();
         wo help;
         wo save;
         help.x=startx;
         help.y=starty;
         step[startx][starty]=0;
         memset(vis,0,sizeof(vis));
         for(int i=1;i<=n;i++){
              for(int j=1;j<=n;j++){
                  help.b[i][j]=a[i][j];
             }
         }
        for(int i1=1;i1<=n;i1++){
            for(int j1=1;j1<=n;j1++){//一个一个地找敌方棋子,敌方棋子攻击范围内的就不能到 
                if(help.b[i1][j1]=='C')castle(i1,j1);
                else if(help.b[i1][j1]=='K')knight(i1,j1);
                else if(help.b[i1][j1]=='B')B(i1,j1);
                else if(help.b[i1][j1]=='Q')queen(i1,j1);
                else if(help.b[i1][j1]=='X')king(i1,j1);
                else if(help.b[i1][j1]=='P')solider(i1,j1);
            }
        }vis[endx][endy]=0;//毕竟吃到国王就赢了,不需考虑其它 
        if(judge(help.x,help.y)==0)return -1;
         p.push(help);
         while(p.size()){
               help=p.front();p.pop();
               if(step[endx][endy]!=inf){
                   return step[endx][endy];
              }
              for(int i=0;i<8;i++){
                        memset(vis,0,sizeof(vis)); 
                  for(int i1=1;i1<=n;i1++){
                        for(int j1=1;j1<=n;j1++){//一个一个地找敌方棋子,敌方棋子攻击范围内的就不能到 
                        if(help.b[i1][j1]=='C')castle(i1,j1);
                        else if(help.b[i1][j1]=='K')knight(i1,j1);
                       else if(help.b[i1][j1]=='B')B(i1,j1);
                      else if(help.b[i1][j1]=='Q')queen(i1,j1);
                        else if(help.b[i1][j1]=='X')king(i1,j1);
                      else if(help.b[i1][j1]=='P')solider(i1,j1);
                     }
                 }vis[endx][endy]=0;
                    if(judge(help.x+dx[i],help.y+dy[i])){//重点开始 ,如果跳到了棋盘上且不会被吃 
                      if(step[help.x+dx[i]][help.y+dy[i]]>step[help.x][help.y]+1){//是走到当前点最优策略才行 
                        step[help.x+dx[i]][help.y+dy[i]]=step[help.x][help.y]+1;
                        save.x=help.x+dx[i];save.y=help.y+dy[i];
                        for(int ii=1;ii<=n;ii++){
                            for(int jj=1;jj<=n;jj++){
                                save.b[ii][jj]=help.b[ii][jj];//继承状态 
                            }
                        }
                        save.b[save.x][save.y]='.';//把被“我”吃到的变成点 
                        p.push(save);
                     }//重点结束 
                  }
              } 
         }
         return -1;
    }
    int main()
    {
       while(scanf("%d",&n)!=EOF){
        memset(step,inf,sizeof(step));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin>>a[i][j];
                if(a[i][j]=='O')me(i,j);
                if(a[i][j]=='X'){
                    endx=i,endy=j;//记录国王位置 
                }
            }
        }
        printf("%d ",solve());
      }
    return 0;
    }
  • 相关阅读:
    quartz 中JobExecutionContext的使用
    Memcached 集群架构方面的问题
    Spring+Quartz 集群
    Spring Quartz 持久化解决方案
    不同版本(2.3,2.4,2.5) web.xml 的web-app头信息
    Spring Framework 4.0.0发布,首次支持Java 8
    Serializable java序列化
    Quartz 有状态的JobDataMap
    JobDataMap 不能被序列化如何解决研究中
    Spring-3.2.5 + Quartz-2.2.1 集群实例(Tomcat+Memcached+Quartz集群session共享)
  • 原文地址:https://www.cnblogs.com/c201904xyorz/p/9990792.html
Copyright © 2011-2022 走看看