记得用数组表示八方向
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct node
{
int vis; int has;
} board[1200][1200];
int Q[120][2],K[120][2],P[120][2];
int main()
{
int row,col,q_num,k_num,p_num,i,j,k,Case = 1;
int k_dir[8][2] = {-1,-2,-1,2,-2,1,-2,-1,1,2,1,-2,2,1,2,-1};
int q_dir[8][2] = {-1,0,-1,1,0,1,1,1,1,0,1,-1,0,-1,-1,-1};
while(cin>>row>>col,row||col)
{
memset(board,0,sizeof(board));
cin>>q_num;
for(i = 0;i < q_num;i++)
{
cin>>Q[i][0]>>Q[i][1];
board[Q[i][0]][Q[i][1]].has = 1;
board[Q[i][0]][Q[i][1]].vis = 1;
}
cin>>k_num;
for(j = 0;j < k_num;j++)
{
cin>>K[j][0]>>K[j][1];
board[K[j][0]][K[j][1]].has = 1;
board[K[j][0]][K[j][1]].vis = 1;
}
cin>>p_num;
for(k = 0;k < p_num;k++)
{
cin>>P[k][0]>>P[k][1];
board[P[k][0]][P[k][1]].has = 1;
board[P[k][0]][P[k][1]].vis = 1;
}
//扫描骑士的攻击范围
for(j = 0;j < k_num;j++)
{
for(i = 0;i < 8;i++) // int k_dir[8][2] = {-1,-2,-1,2,-2,1,-2,-1,1,2,1,-2,2,1,2,-1};
{
int x1 = K[j][1]+k_dir[i][0],y1 = K[j][0] - k_dir[i][1];
if(x1 > col||x1 <= 0||y1 > row||y1 <= 0) continue;
board[y1][x1].vis = 1;
}
}
//扫描皇后的攻击范围
for(i = 0; i < q_num;i++)
{
for(j = 0;j < 8;j++)// int q_dir[8][2] = {-1,0,-1,1,0,1,1,1,1,0,1,-1,0,-1,-1,-1}
{
for(k = 1;;k++)
{
int x1 = Q[i][0]+q_dir[j][0]*k;
int y1 = Q[i][1]+q_dir[j][1]*k;
if(x1<=0||x1>row||y1<=0||y1>col) break;
if(board[x1][y1].has) break;
else board[x1][y1].vis = 1;
}
}
}
int ans = 0;
for(i = 1;i <= row;i++)
for(j = 1;j <= col;j++)
if(!board[i][j].vis)
ans++;
printf("Board %d has %d safe squares.\n",Case++,ans);
}
return 0;
}