ACM/ICPC 之 计算几何入门-叉积-to left test(POJ2318-POJ2398)
POJ2318
本题需要运用to left test不断判断点处于哪个分区,并统计分区的点个数(保证点不在边界和界外),用来做叉积入门题很合适
//计算几何-叉积入门题 //Time:157Ms Memory:828K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define MAXN 5005 struct Point{ int x,y; Point(int xx=0, int yy=0):x(xx), y(yy){} friend bool operator < (Point p1, Point p2){ return (p1.x < p2.x) || (p1.x == p2.x && p1.y < p2.y); } }ul, lr, p[2*MAXN], toy[MAXN]; int n, m; int num[MAXN]; int cross(Point a, Point b, Point s)//叉积-(s在ab左侧返回>0) { return (a.x-s.x) * (b.y-s.y) - (a.y-s.y) * (b.x-s.x); } int main() { //freopen("in.txt", "r", stdin); while(scanf("%d", &n), n) { memset(num, 0, sizeof(num)); scanf("%d%d%d%d%d", &m, &ul.x, &ul.y, &lr.x, &lr.y); for(int i=0; i<n; i++) { int u,l; scanf("%d%d", &u,&l); p[2*i] = Point(u, ul.y); p[2*i+1] = Point(l, lr.y); } p[2*n] = Point(lr.x, ul.y); p[2*n+1] = Point(lr.x, lr.y); for(int i=0; i<m; i++) scanf("%d%d", &toy[i].x, &toy[i].y); sort(toy, toy+m); int cur = 0; for(int i=0; i<m; i++) { for(int j=cur; j<=n; j++) { if(cross(p[j*2+1], p[j*2], toy[i]) > 0) //to left test { num[j]++; break; } } while(toy[i].x > max(p[cur*2+1].x, p[cur*2].x)) cur++; } for(int i = 0; i <= n;i++) printf("%d: %d\n", i, num[i]); printf("\n"); } return 0; }
POJ2398
题意同上,不同在于线段是随机的(需对线段排序),且要求输出为相同统计数的格子数量
//计算几何-叉积入门题-需对线段排序 //题意同POJ2318 //Time:0Ms Memory:724K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define MAXN 1005 struct Point{ int x,y; Point(int xx=0, int yy=0):x(xx), y(yy){} friend bool operator < (Point p1, Point p2){ return (p1.x < p2.x) || (p1.x == p2.x && p1.y < p2.y); } }ul, lr, toy[MAXN]; struct Line{ int a,b,c,d; Line(int aa=0, int bb=0, int cc=0, int dd=0):a(aa),b(bb),c(cc),d(dd){} friend bool operator < (Line l1, Line l2){ return (l1.a < l2.a) || (l1.a == l2.a && l1.c < l2.c); } }line[MAXN]; int n, m; int num[MAXN], cnt[MAXN]; int cross(Point a, Point b, Point s)//叉积-(s在ab左侧返回>0) { return (a.x-s.x) * (b.y-s.y) - (a.y-s.y) * (b.x-s.x); } int main() { //freopen("in.txt", "r", stdin); while(scanf("%d", &n), n) { memset(num, 0, sizeof(num)); memset(cnt, 0, sizeof(cnt)); scanf("%d%d%d%d%d", &m, &ul.x, &ul.y, &lr.x, &lr.y); for(int i=0; i<n; i++) { int u,l; scanf("%d%d", &u,&l); line[i] = Line(u, ul.y, l, lr.y); } line[n] = Line(lr.x, ul.y, lr.x, lr.y); sort(line, line+n+1); for(int i=0; i<m; i++) scanf("%d%d", &toy[i].x, &toy[i].y); sort(toy, toy+m); int cur = 0; for(int i=0; i<m; i++) { for(int j=cur; j<=n; j++) { if(cross(Point(line[j].c, line[j].d), Point(line[j].a,line[j].b), toy[i]) > 0) //to left test { num[j]++; break; } } while(toy[i].x > max(line[cur].a, line[cur].c)) cur++; } for(int i=0; i<=n; i++) cnt[num[i]]++; printf("Box\n"); for(int i = 1; i <= n;i++) if(cnt[i]) printf("%d: %d\n", i, cnt[i]); } return 0; }
他坐在湖边,望向天空,她坐在对岸,盯着湖面