
题目分析:
一个平面被一条线切割会比原来的平面多出一个平面。
如果这个时候再次多出一条跟上面的线平行的线再次切割,那么会又多出一个平面。
如果一条线和别的线产生交点,那么这条线切割平面会多出:
这条直线和别的直线相交出的点的个数+1。
程序设计:
用一个class来表示一条线,这条线的a和b分别用long double表示。然后重载==号来判断两条线段是不是完全相同。
如果判断出来这条直线和之前的直线是一样的,那么这条新的直线是无意义的。所以在后面ans+=的时候判断一下,这条线是不是无意义的。
然后就是使用set,可以自动排除一样的点,也就是“集合”的意义,同样的元素只能在set中出现一次。用set的特性我们来判断新的直线和以前的直线相交了多少个点。我们把相交出现的点的坐标insert入set中。
最后我们到底和多少条直线相交了点,用.size()来获得答案。核心思想是模拟。
参考程序:
#include <iostream>
#include <set>
using namespace std;
int n, ans = 1; //本来就1个平面
long double a, b;
typedef pair<long double, long double> P;
class edge {
public:
long double a, b;
bool operator==(const edge& x) { return (this->a == x.a && this->b == x.b); }
} Line[1002];
bool is2Line[1002];
int main() {
memset(is2Line, 0, sizeof(is2Line));
scanf("%d", &n);
for (int i = 0; i < n; i++) { // i是当前的线,j是之前的线
scanf("%g%g", &a, &b);
set<pair<long double, long double>> Point;
Line[i].a = a;
Line[i].b = b;
for (int j = 0; j < i; j++) {
if (is2Line[j])
continue;
if (Line[i] == Line[j]) { //是之前重复的线,也就是i这条线和j是一样的,这条线没有意义。
is2Line[i] = true;
break;
}
if (Line[i].a == Line[j].a) //不是同一条边,但是平行
continue;
Point.insert(P((Line[j].b - Line[i].b) / (Line[i].a - Line[i].b), Line[i].a * (Line[j].b - Line[i].b) / (Line[i].a - Line[i].b) + Line[i].b));
}
if (!is2Line[i]) //一票否决刚刚计算的重边的答案
ans += Point.size() + 1;
}
printf("%d", ans);
return 0;
}

本文介绍了一个程序设计问题,涉及到平面被线切割的情况。通过使用C++编程,利用class定义线段,并重载==运算符来判断线段是否相同。程序通过set数据结构来排除重复的点,并计算出新线与已有线的交点数量,最终得出切割后平面的数量。核心算法是模拟线与线的交点并统计平面数量。
938

被折叠的 条评论
为什么被折叠?



