zoukankan      html  css  js  c++  java
  • [洛谷3930]SAC E#1

    Description
    他们经常在一起玩一个游戏,不,不是星际争霸,是国际象棋。毒奶色觉得F91是一只鸡。他在一个n×n的棋盘上用黑色的城堡(车)、骑士(马)、主教(象)、皇后(副)、国王(帅)、士兵(卒)摆了一个阵。然而F91觉得毒奶色是一只鸡。他发起了挑战:他要操纵一个白色骑士,不经过任何一个棋子的攻击范围(F91可以连续行动,而毒奶色的棋子不会动,除非白骑士进入了对方的攻击范围),并击杀毒奶色的国王(即进入黑国王所在的位置)。请告诉F91他最少需要多少步骤来完成这一项壮举。
    注意:

    • 当F91的白骑士走到毒奶色的棋子所在的格子上的时候,会击杀(吃掉)该棋子。这个棋子也就不再对F91的白骑士有威胁了。
    • 如果白骑士开场就在黑子的攻击范围内,则立刻被击杀、F91立刻失败。
    • 即使白骑士在攻击王的瞬间进入了其他棋子攻击范围(即其他棋子"看护"着王所在的格子),依然算F91获胜。

    攻击范围:
    城堡:横、竖方向所有位置,直到被一个其他棋子阻拦。

    ..#..
    ..#..
    ##C##
    ..#..
    ..#..
    

    骑士:横2竖1或者横1竖2的所有位置(最多8个,类似日字)。

    .#.#.
    #...#
    ..K..
    #...#
    .#.#.
    

    主教:斜向(45°)所有位置,直到被一个其他棋子阻拦。

    #...#
    .#.#.
    ..B..
    .#.#.
    #...#
    

    皇后:城堡和主教的结合体(既能横/竖向攻击,也能45°角斜向攻击,直到被其他棋子阻挡)。

    #.#.#
    .###.
    ##Q##
    .###.
    #.#.#
    

    国王:身边8连通位置的8个格子。

    .....
    .###.
    .#X#.
    .###.
    .....
    

    士兵:左下方/右下方(45°)的格子(最多2个)。

    .....
    .....
    ..P..
    .#.#.
    .....
    

    其中字母表示棋子类型,参考输入格式。
    '#'表示可攻击范围。

    Input
    输入包含多组数据。
    每一组数据中,第一行一个整数n表示棋盘规模。
    接下来n行,每行一个长度为n的字符串。描述棋盘的格局。
    其中:
    .表示空
    O表示白骑士
    C表示黑城堡
    K表示黑骑士
    B表示黑主教
    Q表示黒皇后
    X表示黑国王
    P表示黑士兵

    Output
    对于每一个测试数据,每行输出一个整数,表示F91的最小步数。
    如果无论F91如何行动也无法击杀黑国王,输出-1。

    Sample Input
    8
    ......X.
    ........
    .O......
    ...P.Q.C8
    .....B..
    ........
    ...K....
    ........

    Sample Output
    7

    HINT
    输入最多包含5组数据。
    对于20%的数据,毒奶色只有国王。n <= 8。
    对于30%的数据,毒奶色只有国王、骑士。n <= 8。
    对于60%的数据,毒奶色只有国王、骑士、王后。n <= 50。
    对于100%的数据,毒奶色可以有全套16颗棋子(2城堡,2骑士,2主教,1后,1王,8兵)。n <= 50。

    温馨提示:时间限制可能比想象之中还要更紧一点,请注意实现细节以保证性能。

    样例2解释:
    一种可行的做法是:

    ......X.
    .3..6...
    .O5.....
    4.2P.Q.C
    1....B..
    ........
    ...K....
    ........
    

    这题看起来真是恶心,不过知道写法之后也还好。。。
    我们设f[x][y][sta]代表当前在(x,y)这个点,吃掉的黑棋状态为sta。bfs每次转移,判断(x,y,sta)这个三元组是否可行(暴力判断可行),然后循环队列优化,碰到'X'就输出答案。
    这题我TM还RE了好几次,最后发现数据里n=55???说好的n<=50呢???

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include <unordered_set>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
        for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
        return x*f;
    }
    inline void print(int x){
        if (x>=10)	print(x/10);
        putchar(x%10+'0');
    }
    const int N=60,M=1e5;
    const int dx[8]={-2,-2,-1,-1,1,1,2,2};
    const int dy[8]={-1,1,-2,2,-2,2,-1,1};
    struct S1{int x,y,dis,sta;}h[M+10];
    unordered_set<int>vis[N][N];
    char A[N][N];
    int ID[N][N],n;
    int in_map(int x,int y){return x>0&&x<=n&&y>0&&y<=n;}
    bool check(int sta,int x,int y){
        if (vis[x][y].count(sta))	return false;
        for (int i=x+1;i<=n;i++){
    	    if (A[i][y]!='.'&&!(sta&(1<<ID[i][y]))){
    		    if (A[i][y]=='C'||A[i][y]=='Q')
    			    return false;
    		    break;
    		}
    	}
        for (int i=x-1;i>=0;i--){
    	    if (A[i][y]!='.'&&!(sta&(1<<ID[i][y]))){
    		    if (A[i][y]=='C'||A[i][y]=='Q')
    			    return false;
    		    break;
    		}
    	}
        for (int j=y+1;j<=n;j++){
    	    if (A[x][j]!='.'&&!(sta&(1<<ID[x][j]))){
    		    if (A[x][j]=='C'||A[x][j]=='Q')
    			    return false;
    		    break;
    		}
    	}
        for (int j=y-1;j>=0;j--){
    	    if (A[x][j]!='.'&&!(sta&(1<<ID[x][j]))){
    		    if (A[x][j]=='C'||A[x][j]=='Q')
    			    return false;
    		    break;
    		}
    	}
        for (int i=x+1,j=y+1;i<=n&&j<=n;i++,j++){
    	    if (A[i][j]!='.'&&!(sta&(1<<ID[i][j]))){
    		    if (A[i][j]=='B'||A[i][j]=='Q')
    			    return false;
    		    break;
    		}
    	}
        for (int i=x+1,j=y-1;i<=n&&j>=0;i++,j--){
    	    if (A[i][j]!='.'&&!(sta&(1<<ID[i][j]))){
    		    if (A[i][j]=='B'||A[i][j]=='Q')
    			    return false;
    		    break;
    		}
    	}
        for (int i=x-1,j=y+1;i>=0&&j<=n;i--,j++){
    	    if (A[i][j]!='.'&&!(sta&(1<<ID[i][j]))){
    		    if (A[i][j]=='B'||A[i][j]=='Q')
    			    return false;
    		    break;
    		}
    	}
        for (int i=x-1,j=y-1;i>=0&&j>=0;i--,j--){
    	    if (A[i][j]!='.'&&!(sta&(1<<ID[i][j]))){
    		    if (A[i][j]=='B'||A[i][j]=='Q')
    			    return false;
    		    break;
    		}
    	}
        for (int k=0;k<8;k++){
    	    int tx=x+dx[k],ty=y+dy[k];
    	    if (!in_map(tx,ty))	continue;
    	    if (A[tx][ty]=='K')	return false;
    	}
        if (x!=1&&((y!=1&&!(sta&(1<<ID[x-1][y-1]))&&A[x-1][y-1]=='P')||(y!=n&&!(sta&(1<<ID[x-1][y+1]))&&A[x-1][y+1]=='P')))
    	    return false;
        for (int i=x-1;i<=x+1;i++){
    	    for (int j=y-1;j<=y+1;j++){
    		    if (!in_map(i,j))	continue;
    		    if (A[i][j]=='X')	return false;
    		}
    	}
        return true;
    }
    int bfs(int ox,int oy){
        int head=0,tail=1;
        h[1]=(S1){ox,oy,0,0};
        vis[ox][oy].insert(0);
        while (head!=tail){
    	    if (++head>M)	head=1;
    	    int Nx=h[head].x,Ny=h[head].y;
    	    for (int k=0;k<8;k++){
    		    int tx=Nx+dx[k],ty=Ny+dy[k],sta=h[head].sta;
    		    if (!in_map(tx,ty))	continue;
    		    if (A[tx][ty]=='X')	return h[head].dis+1;
    		    if (A[tx][ty]!='.')	sta|=1<<ID[tx][ty];
    		    if (check(sta,tx,ty)){
    			    if (++tail>M)	tail=1;
    			    h[tail]=(S1){tx,ty,h[head].dis+1,sta};
    			    vis[tx][ty].insert(sta);
    			}
    		}
    	}
        return -1;
    }
    void init(){memset(ID,255,sizeof(ID));}
    int main(){
        while (~scanf("%d",&n)){
    	    init(); int tot=0,ox=0,oy=0;
    		for (int i=1;i<=n;i++){
    		    scanf("%s",A[i]+1);
    		    for (int j=1;j<=n;j++){
    			    if (A[i][j]=='O')	ox=i,oy=j,A[i][j]='.';
    			    else	if (A[i][j]!='.')	ID[i][j]=++tot;
    			    vis[i][j].clear();
    			}
    		}
    	    if (!check(0,ox,oy)){
    		    printf("-1
    ");
    		    continue;
    		}
    	    printf("%d
    ",bfs(ox,oy));
    	}
        return 0;
    }
    
  • 相关阅读:
    查找网页元素对应的js代码
    29 图片缩小案例
    29 三级缓存案例
    [Angular2]eclipse中angular2开发环境的搭建
    28 自定义View流式布局
    28 自定义滑动开关
    28 自定义View侧滑栏
    28自定义View 模仿联系人字母侧栏
    28 自定义View画坐标和柱状图
    JFinal中使用QuartzPlugin报ClassCastException解决方法
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9650092.html
Copyright © 2011-2022 走看看