1 条题解
-
0
题意分析
该题的核心是折叠,这涉及到直线和点之间的关系,该题给出折叠次数,以其一个折叠后的坐标,要求出有多少个点通过折叠可以到达这个坐标
解题思路
该题的核心重点在于直线对折,在二维平面中,直线的一般式方程为 其中 p1 p2 为直线上的两个点 , a,b之间距离 点p到直线距离 由此可算出p点坐标 x_reflect =
y_reflect = 考虑到从第一条折叠计算点的坐标非常复杂,我们已知折叠到最后点的坐标,不妨反过来从最后点的坐标来求前面可能被折叠的点的坐标。 而如果折叠后的点在直线上或在折叠线右边,则这个点应该舍去,我们只需要在折叠线右边的点,而叉积可以帮助我们。 对于直线上的两个点a,b。直线外一点c 他们的叉积为 $(b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)$ 如果叉积大于0.表明c在直线左侧,这就是我们要找的点
标程
```cpp #include <iostream> #include <vector> #include <cmath> using namespace std; const double EPS = 1e-7; struct Point{ double x,y; Point(double x = 0,double y = 0) : x(x),y(y){} }; double cross(const Point& a,const Point& b, const Point& c){ return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); } Point reflectPoint(const Point& p1, const Point& p2, const Point& p){ double a = p2.y - p1.y; double b = p1.x - p2.x; double c = -(a * p1.x + b * p1.y); double denominator = a * a + b * b; if(std::abs(denominator) < EPS){ return p; } double val = a * p.x + b * p.y + c; double x_reflect = p.x - 2 * a * val / denominator; double y_reflect = p.y - 2 * b * val / denominator; Point newp = Point(x_reflect,y_reflect); return newp; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n_folds; cin >> n_folds; vector<pair<Point,Point>> folds(n_folds); for(int i = 0; i < n_folds; i++){ double x1,x2,y1,y2; cin >> x1 >> y1 >> x2 >> y2; folds[i] = {Point(x1,y1),Point(x2,y2)}; } int n_queries; cin >> n_queries; for(int i = 0; i < n_queries; i++){ double x,y; cin>> x >> y; vector<Point> points = {Point(x,y)}; for(int j = n_folds - 1; j >= 0; j--){ auto [p1,p2] = folds[j]; vector<Point> new_points; for(const Point& p : points){ double d = cross(p1,p2,p); if(std::abs(d) <= EPS){ continue; } if(d > EPS){ new_points.push_back(p); Point newp = reflectPoint(p1,p2,p); new_points.push_back(newp); } } points = new_points; } int count = 0; for (const Point& p : points) { if (p.x > EPS && p.x < 100 - EPS && p.y > EPS && p.y < 100 - EPS) { count++; } } cout << count << endl; } return 0; }
- 1
信息
- ID
- 1617
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者