NC237555. Surround the Buildings
描述
输入描述
The first line contains two integers , indicate the numbers of the villages and the planned sites.
In the following lines, each line contains two integers , indicates the coordinates of the villages.
In the following lines, each line contains two integers , indicates the coordinates of the planned sites.
It is guarantee that there doesn`t exist a line across all the villages.
输出描述
If no solution exists, output on a single line, otherwise output an integer indicating the minimum number of sites to protect all the buildings.
示例1
输入:
3 6 -1 1 -2 -1 2 0 -3 1 3 1 -1 -4 1 2 -4 -5 3 -4
输出:
3
示例2
输入:
3 3 1 1 1 2 2 2 2 1 1 3 0 1
输出:
-1
说明:
Note that there may be some points with the same coordinateC++(g++ 7.5.0) 解法, 执行用时: 2570ms, 内存消耗: 68244K, 提交时间: 2022-09-14 00:22:32
#include <bits/stdc++.h> using namespace std; int fin() { int x = 0, f = 1; char c = getchar(); while (!isdigit(c)) { if (c == '-') f = -1; c = getchar(); } while (isdigit(c)) { x = (x << 1) + (x << 3) + (c - '0'); c = getchar(); } return x * f; } using ll = long long; using ld = long double; using mat = vector<vector<int>>; const int inf = 0x3f3f3f3f; const ld eps = 1e-9; const ld PI = acosl(-1); int sgn(ld x) { if (fabsl(x) < eps) return 0; if (x > 0) return 1; return -1; } struct node { ld x, y; void read() { x = fin(), y = fin(); } node rotate(ld alpha) const { ld cs = cosl(alpha); ld sn = sinl(alpha); return {x * cs - y * sn, x * sn + y * cs}; } node operator-(const node &t) const { return {x - t.x, y - t.y}; } node operator+(const node &t) const { return {x + t.x, y + t.y}; } ld getAlpha() const { return atan2l(y, x); } ld len2() const { return x * x + y * y; } ld len() const { return sqrtl(len2()); } ld operator^(const node &t) const { return x * t.y - y * t.x; } bool operator<(const node &t) const { if (!sgn(x)) return y < t.y; return x < t.x; } bool operator==(const node &t) const { return !sgn(x - t.x) && !sgn(y - t.y); } }; vector<node> tubo(const vector<node> &a, int n) { deque<int> q; vector<bool> vis(n); for (int i = 0; i < n; i++) { while (q.size() >= 2) { int x = q[q.size() - 2], y = q.back(), z = i; node A = a[z] - a[x]; node B = a[y] - a[x]; if (sgn(A ^ B) <= 0) { q.pop_back(); vis[y] = 0; } else break; } q.push_back(i); vis[i] = 1; } vis[0] = 0; for (int i = n - 1; i >= 0; i--) { if (vis[i]) continue; while (q.size() >= 2) { int x = q[q.size() - 2], y = q.back(), z = i; node A = a[z] - a[x]; node B = a[y] - a[x]; if (sgn(A ^ B) <= 0) { q.pop_back(); } else break; } q.push_back(i); } vector<node> res; for (auto to: q) { res.push_back(a[to]); } return res; } int main() { #ifdef _OJ_TEST_ freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif int n = fin(), m = fin(); vector<node> a(n), b(m); for (auto &x: a) x.read(); for (auto &y: b) y.read(); sort(a.begin(), a.end()); sort(b.begin(), b.end()); a.erase(unique(a.begin(), a.end()), a.end()); b.erase(unique(b.begin(), b.end()), b.end()); a = tubo(a, a.size()); n = a.size(); m = b.size(); vector<vector<int>> e(m); for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { if (i == j) continue; node A = b[j] - b[i]; int l = 0, r = n - 2; while (l < r) { int mid = (l + r + 1) >> 1; node B = a[mid + 1] - a[mid]; if (sgn(A ^ B) <= 0) r = mid - 1; else l = mid; } node B = a[l + 1] - b[i]; if (sgn(A ^ B) > 0) { continue; } B = a[l] - b[i]; if (sgn(A ^ B) <= 0) { e[i].push_back(j); } } } auto bfs = [&](int st) { queue<int> q; vector<int> dis(m, inf); q.push(st); dis[st] = 0; while (q.size()) { auto hd = q.front(); q.pop(); for (auto to: e[hd]) { if (to == st) { return dis[hd] + 1; } if (dis[hd] + 1 < dis[to]) { dis[to] = dis[hd] + 1; q.push(to); } } } return inf; }; int res = inf; for (int st = 0; st < m; st++) { res = min(res, bfs(st)); } printf("%d\n", res == inf ? -1 : res); return 0; }
C++ 解法, 执行用时: 1974ms, 内存消耗: 113248K, 提交时间: 2022-05-28 20:47:07
#include<cstdio> #include<vector> #include<algorithm> #include<bitset> #include<queue> using namespace std; const int INF=1e9; struct pnt { long long x,y; pnt(long long _x=0,long long _y=0):x(_x),y(_y){} }; bool operator<(pnt A,pnt B){return A.x!=B.x?A.x<B.x:A.y<B.y;} bool operator==(pnt A,pnt B){return A.x==B.x&&A.y==B.y;} pnt operator+(pnt A,pnt B){return pnt(A.x+B.x,A.y+B.y);} pnt operator-(pnt A,pnt B){return pnt(A.x-B.x,A.y-B.y);} long long operator^(pnt A,pnt B){return A.x*B.y-A.y*B.x;} typedef pnt vec; int n,m; pnt P[2000000],Q[10000]; vector<pnt> U,D; pnt dD[2000000],dU[2000000]; void get_Convex_Hull() { D.push_back(P[1]); for(int i=2;i<=n;i++) { while(D.size()>=2&&((D[D.size()-1]-D[D.size()-2])^(P[i]-D[D.size()-2]))<=0)D.pop_back(); D.push_back(P[i]); } U.push_back(P[n]); for(int i=n-1;i>=1;i--) { while(U.size()>=2&&((U[U.size()-1]-U[U.size()-2])^(P[i]-U[U.size()-2]))<=0)U.pop_back(); U.push_back(P[i]); } } typedef bitset<5001> BIT; BIT E[5001],res;int dis[10000]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%lld%lld",&P[i].x,&P[i].y); } sort(P+1,P+n+1);n=unique(P+1,P+n+1)-(P+1); get_Convex_Hull(); for(int i=0;i<D.size()-1;i++)dD[i]=D[i+1]-D[i]; for(int i=0;i<U.size()-1;i++)dU[i]=U[i+1]-U[i]; for(int i=1;i<=m;i++) { scanf("%lld%lld",&Q[i].x,&Q[i].y); } for(int i=1;i<=m;i++) { for(int j=1;j<=m;j++) { if(i==j)continue; int l=0,r=U.size()-1;vec x=Q[j]-Q[i]; while(l<r) { int mid=(l+r)>>1; if((dU[mid]^x)<=0)l=mid+1;else r=mid; } if(((U[l]-Q[i])^x)<0)continue; l=0,r=D.size()-1; while(l<r) { int mid=(l+r)>>1; if((dD[mid]^x)<=0)l=mid+1;else r=mid; } if(((D[l]-Q[i])^x)<0)continue; E[i][j]=1; } } //for(int i=1;i<=m;i++){for(int j=1;j<=m;j++)printf("%d",(int)E[i][j]);puts("");} ///return 0; queue<int> q; int ans=INF; for(int i=1;i<=m;i++) { //printf("%d:\n",i); for(int j=1;j<=m;j++)dis[j]=-1,res[j]=1; for(int j=1;j<=m;j++)if(E[i][j])dis[j]=1,q.push(j),res[j]=0; while(!q.empty()&&dis[i]==-1) { int x=q.front();BIT B=E[x]&res;q.pop(); while(B.any()) { int u=B._Find_first();B[u]=0;res[u]=0;q.push(u);dis[u]=dis[x]+1; } } if(dis[i]!=-1)ans=min(ans,dis[i]); while(!q.empty())q.pop(); } printf("%d",ans==INF?-1:ans); }