https://www.acmicpc.net/problem/12781
종만북에서 소스를 가져왔다. 벡터로 선분이 평행한지 조사해서 평행하면 0, 아니면 4조각으로
자를 수 있다는 뜻이므로 1을 리턴했다.
#include <iostream> #include <vector> #include <cmath> using namespace std; const double PI = 2.0 * acos(0.0); struct vector2 { double x, y; vector2(double x_ = 0, double y_ = 0) : x(x_), y(y_) {} // 두 벡터가 같은 경우 bool operator == (const vector2& rhs) const { return x == rhs.x && y == rhs.y; } // 벡터의 덧셈과 뺄셈, 단항 연산자의 구현 vector2 operator + (const vector2& rhs) const { return vector2(x + rhs.x, y + rhs.y); } vector2 operator - (const vector2& rhs) const { return vector2(x - rhs.x, y - rhs.y); } vector2 operator - () const { return vector2(-x, -y); } bool operator < (const vector2& rhs) const { return x != rhs.x? x < rhs.x: y < rhs.y; } // 스칼라로 곱셈 vector2 operator * (double rhs) const { return vector2(x * rhs, y * rhs); } // 벡터의 길이를 반환한다 double norm() const { return hypot(x, y); } // 방향이 같은 단위 벡터 (unit vector) 를 반환한다 vector2 normalize() const { double n = norm(); return vector2(x / n, y / n); } // 내적/외적의 구현 double dot(const vector2& rhs) const { return x * rhs.x + y * rhs.y; } double cross(const vector2& rhs) const { return x * rhs.y - rhs.x * y; } // 이 벡터를 rhs 에 사영한 결과 vector2 project(const vector2& rhs) const { vector2 r = rhs.normalize(); return r * r.dot(*this); } }; bool inBoundingRectangle(vector2 p,vector2 a,vector2 b){ if (b < a) swap(a,b); return p == a || p == b || (a < p && p < b); } const double EPSILON = 1e-9; bool lineIntersection(vector2 a,vector2 b,vector2 c,vector2 d,vector2 &x){ //두직선의 교차점을 계산하는함수 double det = (b-a).cross(d-c); if (fabs(det) < EPSILON) return false; x = a+(b-a)*((c-a).cross(d-c)/det); return true; } bool segmentIntersection(vector2 a,vector2 b,vector2 c,vector2 d,vector2 &p){ //a,b선분과 c,d선분의 교점을 p로 반환 if (!lineIntersection(a,b,c,d,p)) return false; // 평행인 경우 예외처리 return inBoundingRectangle(p,a,b)&&inBoundingRectangle(p,c,d); } int main() { vector<vector2> vec; for(int i=0;i<4;i++) { int x,y; cin>>x>>y; vec.push_back(vector2(x,y)); } vector2 ret; if (!segmentIntersection(vec[0],vec[1],vec[2],vec[3],ret)) cout<<"0\n"; else cout<<"1\n"; return 0; }
https://www.acmicpc.net/problem/1708
기하 파트에서 가장 기본적인 알고리즘중 하나인 볼록 껍질 구하는 문제.
#include <iostream> #include <vector> #include <cmath> #include <algorithm> using namespace std; const double PI = 2.0 * acos(0.0); struct vector2 { double x, y; vector2(double x_ = 0, double y_ = 0) : x(x_), y(y_) {} // 두 벡터가 같은 경우 bool operator == (const vector2& rhs) const { return x == rhs.x && y == rhs.y; } // 벡터의 덧셈과 뺄셈, 단항 연산자의 구현 vector2 operator + (const vector2& rhs) const { return vector2(x + rhs.x, y + rhs.y); } vector2 operator - (const vector2& rhs) const { return vector2(x - rhs.x, y - rhs.y); } vector2 operator - () const { return vector2(-x, -y); } bool operator < (const vector2& rhs) const { return x != rhs.x? x < rhs.x: y < rhs.y; } // 스칼라로 곱셈 vector2 operator * (double rhs) const { return vector2(x * rhs, y * rhs); } // 벡터의 길이를 반환한다 double norm() const { return hypot(x, y); } // 방향이 같은 단위 벡터 (unit vector) 를 반환한다 vector2 normalize() const { double n = norm(); return vector2(x / n, y / n); } // 내적/외적의 구현 double dot(const vector2& rhs) const { return x * rhs.x + y * rhs.y; } double cross(const vector2& rhs) const { return x * rhs.y - rhs.x * y; } // 이 벡터를 rhs 에 사영한 결과 vector2 project(const vector2& rhs) const { vector2 r = rhs.normalize(); return r * r.dot(*this); } }; double ccw(vector2 a, vector2 b) { return a.cross(b); } double ccw(vector2 p, vector2 a, vector2 b) { return ccw(a-p, b-p); } typedef vector<vector2> polygon; polygon giftWrap(const vector<vector2>& points) { int n = points.size(); polygon hull; vector2 pivot = *min_element(points.begin(), points.end()); hull.push_back(pivot); while(true) { vector2 ph = hull.back(), next = points[0]; for(int i=1;i<n;i++) { double cross = ccw(ph, next, points[i]); double dist = (next - ph).norm() - (points[i] - ph).norm(); if(cross > 0 || (cross == 0 && dist < 0)) next = points[i]; } if(next==pivot) break; hull.push_back(next); } return hull; } int main() { vector<vector2> vec; int n; cin>>n; for(int i=0;i<n;i++) { int x,y; cin>>x>>y; vec.push_back(vector2(x,y)); } vector<vector2> ret = giftWrap(vec); cout<<ret.size()<<"\n"; return 0; }
https://www.acmicpc.net/problem/9240
간단하다. 볼록 껍질을 구한후 볼록 껍질의 모든 점에 대해 각각의 거리값을 특정 변수에 저장해둔다.
그다음에 가장 큰 값을 출력하면 끝.
#include <iostream> #include <vector> #include <cmath> #include <algorithm> #include <iomanip> using namespace std; const double PI = 2.0 * acos(0.0); struct vector2 { double x, y; vector2(double x_ = 0, double y_ = 0) : x(x_), y(y_) {} // 두 벡터가 같은 경우 bool operator == (const vector2& rhs) const { return x == rhs.x && y == rhs.y; } // 벡터의 덧셈과 뺄셈, 단항 연산자의 구현 vector2 operator + (const vector2& rhs) const { return vector2(x + rhs.x, y + rhs.y); } vector2 operator - (const vector2& rhs) const { return vector2(x - rhs.x, y - rhs.y); } vector2 operator - () const { return vector2(-x, -y); } bool operator < (const vector2& rhs) const { return x != rhs.x? x < rhs.x: y < rhs.y; } // 스칼라로 곱셈 vector2 operator * (double rhs) const { return vector2(x * rhs, y * rhs); } // 벡터의 길이를 반환한다 double norm() const { return hypot(x, y); } // 방향이 같은 단위 벡터 (unit vector) 를 반환한다 vector2 normalize() const { double n = norm(); return vector2(x / n, y / n); } // 내적/외적의 구현 double dot(const vector2& rhs) const { return x * rhs.x + y * rhs.y; } double cross(const vector2& rhs) const { return x * rhs.y - rhs.x * y; } // 이 벡터를 rhs 에 사영한 결과 vector2 project(const vector2& rhs) const { vector2 r = rhs.normalize(); return r * r.dot(*this); } }; double ccw(vector2 a, vector2 b) { return a.cross(b); } double ccw(vector2 p, vector2 a, vector2 b) { return ccw(a-p, b-p); } typedef vector<vector2> polygon; polygon giftWrap(const vector<vector2>& points) { int n = points.size(); polygon hull; vector2 pivot = *min_element(points.begin(), points.end()); hull.push_back(pivot); while(true) { vector2 ph = hull.back(), next = points[0]; for(int i=1;i<n;i++) { double cross = ccw(ph, next, points[i]); double dist = (next - ph).norm() - (points[i] - ph).norm(); if(cross > 0 || (cross == 0 && dist < 0)) next = points[i]; } if(next==pivot) break; hull.push_back(next); } return hull; } int main() { vector<vector2> vec; int n; cin>>n; for(int i=0;i<n;i++) { int x,y; cin>>x>>y; vec.push_back(vector2(x,y)); } vector<vector2> ret = giftWrap(vec); //볼록 껍질 좌표 목록들. vector<double> dis; for(int i=0;i<ret.size();i++) { //cout<<ret[i].x<<" "<<ret[i].y<<"\n"; for(int j=0;j<ret.size();j++) if(i!=j) //두 점이 다르면 거리값을 dis벡터에 저장해둠. dis.push_back(sqrt(pow(ret[i].y-ret[j].y, 2) + pow(ret[i].x-ret[j].x,2))); } if(ret.size()==1) //볼록 껍질 사이즈가 1일경우 모든 점이 같다는 소리이므로 거리 0을 저장해둠. dis.push_back(0.0); cout<<setprecision(12)<<*max_element(dis.begin(), dis.end())<<"\n"; //10^-6의 정확도 + max_element로 결과값을 구해줌. //for(int i=0;i<dis.size();i++) // cout<<setprecision(11)<<dis[i]<<endl; return 0; }
'algorithm > problem solving' 카테고리의 다른 글
acmicpc.net 1535(배낭 문제, DP), 1915(DP), 1562(비트마스크, DP) (0) | 2016.11.01 |
---|---|
acmicpc.net 3878(볼록 껍질, 기하), 2254(볼록 껍질, 기하), 2166(기하) (0) | 2016.10.30 |
acmicpc.net 9934(트리, BFS), 5639(이진 트리), 6597(트리) (0) | 2016.10.28 |
acmicpc.net 1967,1167(트리,DFS), 11725(트리,DFS), 1068(트리,DFS) (0) | 2016.10.27 |
acmicpc.net 7562(BFS), 3055(BFS), 7576,7569(BFS) (0) | 2016.10.25 |