1. 程式人生 > >B - Security Guards Gym - 101954B[預處理BFS]

B - Security Guards Gym - 101954B[預處理BFS]

題意:在二維平面內有n個消防站,現在有Q次詢問,每次詢問給出一個座標代表事故現場的地點,問距離該點最近的消防站的距離是多少。
距離的定義:一個點到他周圍八個方向的點的距離都是1.


題解:我們先把所有消防站的點壓入一個佇列中去,然後進行BFS,通過BFS記錄到達某個點的最短距離,最先搜到的一定是最短距離。


a c   c

o d e : ac\ code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++) #define per(i, a, b) for(int i = a; i >= b; i--) const int maxn = 5500 + 10; const int inf = 0x3f3f3f3f; const int mod = 1e9 + 7; inline int read() { int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') {if(ch == '-')
f = -1; ch = getchar();} while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();} return f * x; } ll qp(ll base, ll n) { ll res = 1; while(n) { if(n & 1) res = (res * base) % mod; base = (base * base) % mod; n >>= 1; } return res; } ll inv[maxn], fac[maxn]; void init() { fac[0] = 1; rep(i, 1, maxn - 1) { fac[i] = fac[i - 1] * i % mod; } inv[maxn - 1] = qp(fac[maxn - 1], mod - 2); per(i, maxn - 2, 0) { inv[i] = inv[i + 1] * (i + 1) % mod; //printf("%lld %lld\n", inv[i], qp(fac[i], mod - 2)); } } ll C(ll n, ll r) { if(n < r ||r < 0) return 0; return fac[n] * inv[r] % mod * inv[n - r] % mod; } char s[maxn]; int main() { init(); int n, k; while(~scanf("%d%d", &n, &k)) { scanf("%s", s); if(n == 1) { if(k == 0) { if(s[0] == '1') puts("0"); else puts("1"); } else { if(s[0] == '1') puts("2"); else puts("1"); } } else { ll ans = 0; int x = k; rep(i, 0, n - 1) { if(s[i] == '0') { if(x > 0) ans = (ans + C(n - i - 1, x - 1)) % mod; } else { x--; } } if(x == 0) ans++; x = k - 1; rep(i, 0, n - 1) { if(s[i] == '1') { if(x >= 0) ans = (ans + C(n - i - 1, x)) % mod; x--; } } printf("%lld\n", ans % mod); } } return 0; }