Sicily 1172. Queens, Knights and Pawns

  1. Queens, Knights and Pawns
    Constraints
    Time Limit: 1 secs, Memory Limit: 64 MB
    Description
    You all are familiar with the famous 8-queens problem which asks you to place 8 queens on a chess board so no two attack each other. In this problem, you will be given locations of queens and knights and pawns and asked to find how many of the unoccupied squares on the board are not under attack from either a queen or a knight (or both). We’ll call such squares “safe” squares. Here, pawns will only serve as blockers and have no capturing ability. The board below has 6 safe squares. (The shaded squares are safe.)

Recall that a knight moves to any unoccupied square that is on the opposite corner of a 2x3 rectangle from its current position; a queen moves to any square that is visible in any of the eight horizontal, vertical, and diagonal directions from the current position. Note that the movement of a queen can be blocked by another piece, while a knight’s movement can not.
Input
There will be multiple test cases. Each test case will consist of 4 lines. The first line will contain two integers n and m, indicating the dimensions of the board, giving rows and columns, respectively. Neither integer will exceed 1000. The next three lines will each be of the form
k r1 c1 r2 c2 … rk ck
indicating the location of the queens, knights and pawns, respectively. The numbering of the rows and columns will start at one. There will be no more than 100 of any one piece. Values of n = m = 0 indicate end of input.
Output
Each test case should generate one line of the form
Board b has s safe squares.
where b is the number of the board (starting at one) and you supply the correct value for s.
Sample Input
4 4
2 1 4 2 4
1 1 2
1 2 3
2 3
1 1 2
1 1 1
0
1000 1000
1 3 3
0
0
0 0
Sample Output
Board 1 has 6 safe squares.
Board 2 has 0 safe squares.
Board 3 has 996998 safe squares.
这道题的题意就是找棋盘上安全的点,唯一麻烦的地方就是其他棋子可能阻挡到皇后的线路,我使用了二位数组,通过标记不同的数字区分棋盘是否安全,有一些参数,若元素为0,表示安全,若元素为1,表示被皇后占据,若为2,表示被马占据,若为3,表示被兵占据,若为4,表示在马或者皇后的攻击范围之内,
判断位置是否合法
在这里插入图片描述
马的攻击范围
在这里插入图片描述
在这里插入图片描述
皇后的攻击范围比较大,而且受到兵的干扰,所以我这里用了最笨拙的方法就是八个方向依次罗列,碰到其他棋子,就停止攻击
代码如下
上下左右4个方向
在这里插入图片描述
在这里插入图片描述
左上,左下,右上,右下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<cstring>
using namespace std;
struct queen{
	int x;
	int y;
};
struct knight{
	int x;
	int y;
};
struct pawn{
	int x;
	int y;
};
int kx[8]={-2,-2,-1,-1,1,1,2,2};
int ky[8]={1,-1,2,-2,2,-2,1,-1};
int inq[1005][1005];
bool valid(int x,int y,int nx,int ny){
	if(x>nx||y>ny||x<1||y<1||inq[x][y]!=0){
		return false;
	}
	return true;
} 
int main(){
	int x,y;
	int times=1;
	while(cin>>x>>y&&(x!=0&&y!=0)){
		queen q[100];
		knight k[100];
		pawn p[100];
		memset(inq,0,sizeof(inq));
		int numq;
		cin>>numq;
		for(int i=0;i<numq;i++){
			int x_,y_;
			cin>>x_>>y_;
			q[i].x=x_;
			q[i].y=y_;
			inq[x_][y_]=1;
		}
		int numk;
		cin>>numk;
		for(int i=0;i<numk;i++){
			int x_,y_;
			cin>>x_>>y_;
			k[i].x=x_;
			k[i].y=y_;
			inq[x_][y_]=2;
		}
		int nump;
		cin>>nump;
		for(int i=0;i<nump;i++){
			int x_,y_;
			cin>>x_>>y_;
			p[i].x=x_;
			p[i].y=y_;
			inq[x_][y_]=3;
		}
		for(int i=0;i<numk;i++){
			int x_,y_;
			x_=k[i].x;
			y_=k[i].y;
			for(int j=0;j<8;j++){
				int newx=x_+kx[j];
				int newy=y_+ky[j];
				if(valid(newx,newy,x,y)){
					inq[newx][newy]=4;
				}
			}
		}
		for(int i=0;i<numq;i++){
			int x_,y_;
			x_=q[i].x;
			y_=q[i].y;
			for(int j=x_;j>0;j--){
				if(inq[j][y_]==3||inq[j][y_]==2){
					break;
				}
				if(valid(j,y_,x,y)){
					inq[j][y_]=4;
				}
			}
			for(int j=x_;j<=x;j++){
				if(inq[j][y_]==3||inq[j][y_]==2){
					break;
				}
				if(valid(j,y_,x,y)){
					inq[j][y_]=4;
				}
			}
			for(int j=y_;j<=y;j++){
				if(inq[x_][j]==3||inq[x_][j]==2){
					break;
				}
				if(valid(x_,j,x,y)){
					inq[x_][j]=4;
				}
			}
			for(int j=y_;j>=0;j--){
				if(inq[x_][j]==3||inq[x_][j]==2){
					break;
				}
				if(valid(x_,j,x,y)){
					inq[x_][j]=4;
				}
			}
			int newx1=x_;
			int newy1=y_;
			while(1){
				if(newx1>=1&&newy1>=1&&(inq[newx1][newy1]!=2&&inq[newx1][newy1]!=3)){
					newx1--;
					newy1--;
					if(inq[newx1][newy1]==2){
						
					}
					else if(inq[newx1][newy1]==3){
						
					}
					else{
						inq[newx1][newy1]=4;
					}
				}
				else{
					break;
				}
			}
			int newx2=x_;
			int newy2=y_;
			while(1){
				if(newx2>=1&&newy2<=y&&(inq[newx2][newy2]!=2&&inq[newx2][newy2]!=3)){
					newx2--;
					newy2++;
					if(inq[newx2][newy2]==2){
						
					}
					else if(inq[newx2][newy2]==3){
						
					}
					else{
						inq[newx2][newy2]=4;
					}
				}
				else{
					break;
				}
			}
			int newx3=x_;
			int newy3=y_;
			while(1){
				if(newx3<=x&&newy3<=y&&(inq[newx3][newy3]!=2&&inq[newx3][newy3]!=3)){
					newx3++;
					newy3++;
					if(inq[newx3][newy3]==2){
						
					}
					else if(inq[newx3][newy3]==3){
						
					}
					else{
						inq[newx3][newy3]=4;
					}
				}
				else{
					break;
				}
			}
			int newx4=x_;
			int newy4=y_;
			while(1){
				if(newx4<=x&&newy4>=1&&(inq[newx4][newy4]!=2&&inq[newx4][newy4]!=3)){
					newx4++;
					newy4--;
					if(inq[newx4][newy4]==2){
						
					}
					else if(inq[newx4][newy4]==3){
						
					}
					else{
						inq[newx4][newy4]=4;
					}
				}
				else{
					break;
				}
			}
		}
		int count=0;
		for(int i=1;i<=x;i++){
			for(int j=1;j<=y;j++){
				if(inq[i][j]==0){
					count++;
				//	cout<<i<<' '<<j<<endl;
				}
			}
		}
		cout<<"Board "<<times<<" has "<<count<<" safe squares."<<endl;
		times++;
	}
}


猜你喜欢

转载自blog.csdn.net/dcy19991116/article/details/89472604
今日推荐