Codeforces Round #379 (Div. 2) D. Anton and Chess 模拟

题目链接:

http://codeforces.com/contest/734/problem/D

D. Anton and Chess

time limit per test4 seconds
memory limit per test256 megabytes
#### 问题描述 > Anton likes to play chess. Also, he likes to do programming. That is why he decided to write the program that plays chess. However, he finds the game on 8 to 8 board to too simple, he uses an infinite one instead. > > The first task he faced is to check whether the king is in check. Anton doesn't know how to implement this so he asks you to help. > > Consider that an infinite chess board contains one white king and the number of black pieces. There are only rooks, bishops and queens, as the other pieces are not supported yet. The white king is said to be in check if at least one black piece can reach the cell with the king in one move. > > Help Anton and write the program that for the given position determines whether the white king is in check. > > Remainder, on how do chess pieces move: > > Bishop moves any number of cells diagonally, but it can't "leap" over the occupied cells. > Rook moves any number of cells horizontally or vertically, but it also can't "leap" over the occupied cells. > Queen is able to move any number of cells horizontally, vertically or diagonally, but it also can't "leap". #### 输入 > The first line of the input contains a single integer n (1 ≤ n ≤ 500 000) — the number of black pieces. > > The second line contains two integers x0 and y0 ( - 109 ≤ x0, y0 ≤ 109) — coordinates of the white king. > > Then follow n lines, each of them contains a character and two integers xi and yi ( - 109 ≤ xi, yi ≤ 109) — type of the i-th piece and its position. Character 'B' stands for the bishop, 'R' for the rook and 'Q' for the queen. It's guaranteed that no two pieces occupy the same position. #### 输出 > The only line of the output should contains "YES" (without quotes) if the white king is in check and "NO" (without quotes) otherwise. ####样例输入 > 2 > 4 2 > R 1 1 > B 1 5

样例输出

YES

题意

给你一个地图很大的国际象棋棋盘,其中白的只有王,黑的有若干个王后(既能走直线,又能走对角),象(走对角线),车(直着走),问你能不能将死白棋的王,(注意,黑棋要攻击到王,王要在该黑棋的攻击范围内,且中间不能跳过其他棋子)

题解

因为中间有其他的点而攻击不到王的只有两种情况:
1、车和王之间夹了一个象。
2、象或者王后和王之间夹了一个车。

所以我们只要分别维护离王最近的八个方向的车、象就可以了。然后枚举每一个黑子,判断中间是否有被阻挡。

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf

typedef __int64 LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;

const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);

//start----------------------------------------------------------------------

const int maxn=500000+10;

int n;
int x_0,y_0;

PII Rrr[8],Brr[8];
int vR[8],vB[8];
PII in[maxn];
char inc[maxn];

LL dis(PII pt){
    return (LL)abs(x_0-pt.X)+(LL)abs(y_0-pt.Y);
}

int Dir(PII pt){
    int res=-1;
    if(pt.X==x_0){
        if(pt.Y>y_0) res=3;
        else res=7;
    }
    else if(pt.Y==y_0){
        if(pt.X>x_0) res=1;
        else res=5;
    }
    else if(pt.X+pt.Y==x_0+y_0){
        if(pt.X<x_0&&pt.Y>y_0) res=4;
        else res=0;
    }else if(pt.X-x_0==pt.Y-y_0){
        if(pt.X<x_0&&pt.Y<y_0) res=6;
        else res=2;
    }
    return res;
}

int main() {
    clr(vR,0);
    clr(vB,0);
    scf("%d",&n);
    scf("%d%d",&x_0,&y_0);
    rep(i,0,n){
        char type[11];
        scf("%s%d%d",type,&in[i].X,&in[i].Y);
        inc[i]=type[0];
        int dir=Dir(in[i]);
        if(dir==-1) continue;
        if(type[0]=='R'){
            if(dir%2==0){
                if(vR[dir]==false){
                    vR[dir]=true;
                    Rrr[dir]=in[i];
                }else{
                    if(dis(in[i])<dis(Rrr[dir])){
                        Rrr[dir]=in[i];
                    }
                }
            }
        }else if(type[0]=='B'){
            if(dir%2){
                if(vB[dir]==false){
                    vB[dir]=true;
                    Brr[dir]=in[i];
                }else{
                    if(dis(in[i])<dis(Brr[dir])){
                        Brr[dir]=in[i];
                    }
                }
            }
        }
    }
    bool su=false;
    rep(i,0,n){
        int dir=Dir(in[i]);
        if(dir==-1) continue;
        if(inc[i]=='B'||inc[i]=='Q'){
            if(dir%2==0){
                if(vR[dir]==false||vR[dir]&&dis(in[i])<dis(Rrr[dir])){
                    su=true;
                }
            }
        }
        if(inc[i]=='R'||inc[i]=='Q'){
            if(dir%2==1){
                if(vB[dir]==false||vB[dir]&&dis(in[i])<dis(Brr[dir])){
                    su=true;
                }
            }
        }
        if(su) break;
    }
    if(su) prf("YES\n");
    else prf("NO\n");
    return 0;
}

//end-----------------------------------------------------------------------

写搓了,其实只要维护八个方向离王最近的点,然后看这些点有没有能攻击到王的就可以了。。

posted @ 2016-12-10 23:37  fenicnn  阅读(223)  评论(0编辑  收藏  举报