//Kactl based implementation #include using namespace std; #define rep(i, a, b) for(int i = a; i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() typedef long long ll; typedef pair pii; typedef vector vi; template int sgn(T x) { return (x > 0) - (x < 0); } template struct Point { typedef Point P; T x, y; explicit Point(T x=0, T y=0) : x(x), y(y) {} bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y); } bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); } P operator+(P p) const { return P(x+p.x, y+p.y); } P operator-(P p) const { return P(x-p.x, y-p.y); } P operator*(T d) const { return P(x*d, y*d); } P operator/(T d) const { return P(x/d, y/d); } T dot(P p) const { return x*p.x + y*p.y; } T cross(P p) const { return x*p.y - y*p.x; } T cross(P a, P b) const { return (a-*this).cross(b-*this); } T dist2() const { return x*x + y*y; } double dist() const { return sqrt((double)dist2()); } // angle to x-axis in interval [-pi, pi] double angle() const { return atan2(y, x); } P unit() const { return *this/dist(); } // makes dist()=1 P perp() const { return P(-y, x); } // rotates +90 degrees P normal() const { return perp().unit(); } // returns point rotated 'a' radians ccw around the origin P rotate(double a) const { return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); } friend ostream& operator<<(ostream& os, P p) { return os << "(" << p.x << "," << p.y << ")"; } }; typedef Point P; //This is just modifying the kactl implementation to count the (non-edge) diameters //Since a proper rotating calipers implementation should generate all antipodal pairs //This [should] find all the diameters. pair getDiameters(vector

S){ int n = sz(S), j = n < 2 ? 0 : 1; ll best = 0; set> antiPodal; rep(i,0,j) for (;; j = (j + 1) % n) { if((S[i] - S[j]).dist2() > best) { best = (S[i] - S[j]).dist2(); antiPodal.clear(); } if(best == (S[i] - S[j]).dist2()){ antiPodal.insert({min(S[i],S[j]),max(S[i],S[j])}); } if ((S[(j + 1) % n] - S[j]).cross(S[i + 1] - S[i]) >= 0) break; } for(int i = 0; i < S.size(); i++){ P a = S[i]; P b = S[(i+1)%S.size()]; if(antiPodal.count({a,b})) antiPodal.erase({a,b}); if(antiPodal.count({b,a})) antiPodal.erase({b,a}); } return {best,antiPodal.size()}; } ll safeIntegerSqrt(ll x){ ll r = sqrtl(x) + 10; //sqrtl should actually be safe in this case while(r*r > x) r--; return r; } int main(){ cin.tie(0)->sync_with_stdio(0); ll n,k; cin >> n >> k; vector

poly(n); for(int i = 0; i < n; i++){ cin >> poly[i].x >> poly[i].y; } //best approach is to cut across the diameter until you run //out and have to use d-epsilon, so we need diameter cnt. auto[d2,cnt] = getDiameters(poly); //All of this logic is equivalent to finding the C //for which 2sqrt(D)C >= K while also //having a flag for exact equality so we can //increase the answer by 1 if there is an insufficient //number of diameter occurrences. ll k2Overd2 = (k*k)/(d2*4ll); ll rem = ((k*k)%(d2*4ll)); ll c = safeIntegerSqrt(k2Overd2); if(c*c < k2Overd2 || rem!=0) c++; bool isPerfectSquare = (c*c == k2Overd2); ll ans = c; bool rigid = isPerfectSquare && (rem==0); if(rigid && c>cnt) ans++; cout << ans << "\n"; return 0; }