POJ 2734 Queens, Knights and Pawns

数学模型:

  已知一个n*m的国际象棋的棋盘,有qn个皇后,kn个骑士,pn的士兵(士兵不能动),士兵不能动,皇后和骑士的走法不变,求棋盘有多少格子没被占用和被皇后和骑士攻击到。

分析:

  因为皇后的走法覆盖面较广,所以给每个格子设四个标记,表示是否被皇后的四个方向的攻击到,因为状态数少,可以按位标记,来整合成一个整数,分别为1,2,4,8

 

View Code
#include<cstdio>
#include<cstring>
#define MAXN 1010
using namespace std;

struct Piece
{
    int row,col;
};

Piece Q[MAXN],K[MAXN],P;
int chess[MAXN][MAXN];
int jump[8][2]={{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};

int main()
{
    int i,j,k,ii,jj,n,m,qn,kn,pn,t,T;
    for(T=1;scanf("%d%d",&n,&m),n+m;T++)
    {
        memset(chess,0,sizeof(chess));
        scanf("%d",&qn);
        for(i=0;i<qn;i++)
        {
            scanf("%d%d",&Q[i].row,&Q[i].col);
            chess[Q[i].row][Q[i].col]=15;
        }
        scanf("%d",&kn);
        for(i=0;i<kn;i++)
        {
            scanf("%d%d",&K[i].row,&K[i].col);
            chess[K[i].row][K[i].col]=15;
        }
        scanf("%d",&pn);
        for(i=0;i<pn;i++)
        {
            scanf("%d%d",&P.row,&P.col);
            chess[P.row][P.col]=15;
        }
        for(qn--;qn>=0;qn--)
            for(k=0;k<9;k++)
                if(k!=4)
                {
                    ii=k/3-1,jj=k%3-1;
                    if(ii==0)
                        t=1;
                    else if(ii==jj)
                        t=2;
                    else if(jj==0)
                        t=4;
                    else
                        t=8;
                    for(i=Q[qn].row+ii,j=Q[qn].col+jj;;i+=ii,j+=jj)
                    {
                        if(i<1||j<1||i>n||j>m||(chess[i][j]&t))
                            break;
                        chess[i][j]|=t;
                    }
                }
        for(kn--;kn>=0;kn--)
            for(k=0;k<8;k++)
            {
                ii=jump[k][0];
                jj=jump[k][1];
                i=K[kn].row+ii,j=K[kn].col+jj;
                if(i<1||j<1||i>n||j>m||chess[i][j])
                    continue;
                chess[i][j]|=15;
            }
        for(i=1,k=0;i<=n;i++)
            for(j=1;j<=m;j++)
            {
                if(!chess[i][j])
                    k++;
            }
        printf("Board %d has %d safe squares.\n",T,k);
    }
    return 0;
}

 

 

 

  

posted @ 2012-06-21 09:07    阅读(541)  评论(0编辑  收藏  举报