题意
有n个棋子,棋子在 ( x , y ) (x,y) (x,y)时可以移动至 ( x ± 2 , y ± 1 ) (x\pm2,y\pm1) (x±2,y±1)或 ( x ± 1 , y ± 2 ) (x\pm1,y\pm2) (x±1,y±2)。棋盘无限大,每个棋子允许移动的步数不同,第i个棋子允许移动ki步,棋盘上共有多少个不同的位置能被棋子到达。
题解:
n ≤ 30 , k i ≤ 50 n\le30,k_i\le50 n≤30,ki≤50,每个棋子允许移动的步数小于等于50,每次移动最多往某个方向移动两步,所以棋子的活动范围是有限的,大约在200*200的范围内。对每个棋子BFS,求其能到达的位置即可。注意去重,可以考虑SET。
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<set>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-7
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 100000;
const int mod = 998244353;
int a[220][220], x[36], y[36], k[36];
int dx[8]={2,2,-2,-2,1,1,-1,-1}, dy[8]={1,-1,1,-1,2,-2,2,-2};
set<P> st;
void bfs(int x, int y, int k);
int main()
{
int n, i, j;
while(scanf("%d", &n), n)
{
st.clear();
for(i=0;i<n;i++){
scanf("%d %d %d", &x[i], &y[i], &k[i]);
bfs(x[i], y[i], k[i]);
}
printf("%d\n", st.size());
}
return 0;
}
void bfs(int x, int y, int k)
{
queue<P> que;
memset(a, -1, sizeof(a));
a[110][110] = 0;
que.push(P(110, 110));
while(!que.empty())
{
P p = que.front();que.pop();
if(a[p.first][p.second] < k)
for(int i=0;i<8;i++){
int nx = p.first+dx[i], ny = p.second+dy[i];
if(a[nx][ny] == -1){
a[nx][ny] = a[p.first][p.second]+1;
que.push(P(nx, ny));
}
}
}
for(int i=0;i<=215;i++)
for(int j=0;j<=215;j++)
if(a[i][j] != -1)st.insert(P(i-110+x, j-110+y));
}