SGU235The Queen(BFS)

题意:

一个n∗n的棋盘,每个位置上可以放黑子,白子,皇后(有且仅有一个)或不放。问皇后走m步后能走到多少个不同的格子。皇后可以走上下左右斜任意长度只要没遇到W,遇到B后会停下,B不在存在。

tip:

bfs。。首先我们得知道假如p步可以到的格子,那么第p+2k(k≥1)
步都可以到,因为可以来回走,所以每个点记录奇数点来还是偶数,,
注意一个点如果因为是黑的停下了,那么像一个方向能走到的点再从那个点走反方向到的点(这时候这个黑的被打掉了,写代码可以从这个黑的走这个反方向),那么从这个黑的走两步可以走到黑的后面的。。(正常是走1,3,5、、、步)内存限制比较多。。。bool vis

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
typedef pair<int,int>pi;
typedef pair<int,pi> pii;
const int maxn = 310;
char s[maxn][maxn];
int dir[8][2] = {{0,1},{0,-1},{1,0},{-1,0},{1,1},{-1,-1},{1,-1},{-1,1} };
int n,m,stx,sty;
bool vis[maxn][maxn][2];
void init(){
    scanf("%d%d",&n,&m);
    for(int i = 0 ; i < n ; i++){
        scanf("%s",s[i]);
        for(int j = 0 ; j < n ; j++)
            if(s[i][j] == 'Q')  stx = i,sty = j;
    }
    s[stx][sty] = '.';
}
pii st[maxn*maxn],q[maxn*maxn*2];
int lq,rq;
void sov(){
    int pret = 0,top = 0;
   // vis[stx][sty][0] = true;
    q[++rq] = (make_pair(stx,make_pair(sty,0)));
    while(lq < rq || top){
        pii tmp = q[++lq];
        int x = tmp.first,y = tmp.second.first,t = tmp.second.second;
        int nowx = x,nowy = y;
        if( t > q[lq-1].second.second){
            while(top){
                q[++rq] = st[top--];
            }
        }
        if(t + 1 <= m){
            for(int i = 0 ; i < 8 ; i++){
                nowx =x+ dir[i][0],nowy = y+dir[i][1];
                while(nowx >= 0 && nowx < n && nowy >= 0 && nowy < n && s[nowx][nowy] != 'W'){
                    if(vis[nowx][nowy][(t+1)%2] == false){
                        vis[nowx][nowy][(t+1)%2] = true;
                        q[++rq] = (make_pair(nowx,make_pair(nowy,t+1)));
                    }
                    if(s[nowx][nowy] == 'B')    break;
                    nowx += dir[i][0],nowy += dir[i][1];
                }
            }
        }

        if(t+2 <= m){
            if(s[x][y] == 'B'){
                for(int i = 0 ; i < 8 ; i++){
                    nowx = x;nowy = y;
                    if(s[x-dir[i][0]][y-dir[i][1]] == 'W')    continue;
                    nowx += dir[i][0],nowy += dir[i][1];
                    while(nowx >= 0 && nowx < n && nowy >= 0 && nowy < n && s[nowx][nowy] != 'W' ){
                        if( vis[nowx][nowy][(t+2)%2] == false){
                            vis[nowx][nowy][(t+2)%2] = true;
                            st[++top] = make_pair(nowx,make_pair(nowy,t+2));
                        }

                        if(s[nowx][nowy] == 'B')    break;
                        nowx += dir[i][0],nowy += dir[i][1];
                    }
                }
            }
        }
    }
    int ans = 0;
    for(int i = 0 ; i < n ; i++){
        for(int j =  0 ; j < n ; j++){
            ans += vis[i][j][m%2];
            //if(vis[i][j][m%2])  cout <<i <<"  "<<j <<endl;
        }
    }
    printf("%d\n",ans);
}
int main(){
    init();
    if(m == 0)  printf("1\n");
    else sov();
}
/*
3 2
Q..
BBW
...
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值