链接:https://cn.vjudge.net/contest/68968

POJ 2318 TOYS

题意:m个玩具落在n+1个区间,给你玩具的坐标,问每个区间有多少玩具。

思路:叉积的简单应用,用叉积判断在直线的哪一侧,因为是顺序给出坐标,所以从左往右判断即可。

AC代码:

 #include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 5e3 + ;
int U[maxn], L[maxn], ans[maxn];
int Cross(int x1, int y1, int x2, int y2)
{
return x1 * y2 - x2 * y1;
}
int main()
{
int n, m, x1, y1, x2, y2;
int a, b;
while(~scanf("%d",&n) && n)
{
scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);
for(int i = ;i < n;i++)
{
scanf("%d %d",&U[i], &L[i]);
}
for(int i = ;i <= n;i++) ans[i] = ;
while(m--)
{
scanf("%d%d",&a, &b);
int i = ;
for(i = ;i < n;i++)
{
if(Cross(a - L[i], b - y2, U[i] - L[i], y1 - y2) <= ) break;
}
ans[i]++;
}
for(int i = ;i <= n;i++) printf("%d: %d\n",i, ans[i]);
printf("\n");
}
return ;
}

POJ 2398 Toy Storage

题意:同上一题类似,不过需要排序和改变输出。

AC代码:

 #include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 5e3 + ;
int U[maxn], L[maxn], ans[maxn], num[maxn];
int Cross(int x1, int y1, int x2, int y2)
{
return x1 * y2 - x2 * y1;
}
int main()
{
int n, m, x1, y1, x2, y2;
int a, b;
while(~scanf("%d",&n) && n)
{
scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);
for(int i = ;i < n;i++)
{
scanf("%d %d",&U[i], &L[i]);
}
sort(U, U + n);
sort(L, L + n);
for(int i = ;i <= n;i++) ans[i] = num[i] = ;
while(m--)
{
scanf("%d%d",&a, &b);
int i = ;
for(i = ;i < n;i++)
{
if(Cross(a - L[i], b - y2, U[i] - L[i], y1 - y2) <= ) break;
}
num[i]++;
}
for(int i = ;i <= n;i ++) ans[num[i]] ++;
printf("Box\n");
for(int i = ;i <= n;i++)if(ans[i]) printf("%d: %d\n",i, ans[i]);
}
return ;
}

POJ 3304 Segments

题意:给出n条线段两个端点的坐标,问所有线段投影到一条直线上,如果这些所有投影至少相交于一点就输出Yes!,否则输出No!。

思路:枚举所有端点,判断与其他线段相不相交,至于为什么,画个图吧,反正我理解挺久的。

AC代码:

 #include<cstdio>
#include<cmath>
using namespace std;
const double eps = 1e-;
struct Point{
double x, y;
Point(double _x = , double _y = ):x(_x),y(_y){}
};
double Multi(Point p1, Point p2, Point p0) {
return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x);
}
int n;
struct Line{
Point a, b;
};
Line line[];
bool check(Point a, Point b)
{
if(fabs(a.x - b.x) < eps && fabs(a.y - b.y) < eps) return false;
for(int i = ;i < n;i++)
{
if (Multi(line[i].a, b, a) * Multi(line[i].b, b, a) > ) return false; }
return true;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
double x1, y1, x2, y2;
for(int i = ;i < n;i++)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
line[i].a = Point(x1, y1);
line[i].b = Point(x2, y2);
}
if(n == ){ printf("Yes!\n");continue;}
bool flag = false;
for(int i = ;i < n && !flag;i++)
{
if (check(line[i].a, line[i].b)) flag = true;
for(int j = i + ;j < n && !flag;j++)
{
if(check(line[i].a, line[j].a) ||
check(line[i].a, line[j].b) ||
check(line[i].b, line[j].a) ||
check(line[i].b, line[j].b))
flag = true;
}
}
if(flag) printf("Yes!\n");
else printf("No!\n");
}
return ;
}

POJ 1269 Intersecting Lines

题意:俩条直线相交,相交则输出交点。

AC代码:

 #include<cstdio>
#include<cmath>
using namespace std;
const double eps = 1e-;
struct Point{
double x, y;
Point(double _x = , double _y = ):x(_x),y(_y){}
}a, b, c, d;
typedef Point Vector;
Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x; }//叉积
Point GetLineIntersection(Point P, Vector v, Point Q, Vector w){
Vector u = P - Q;
double t = Cross(w,u)/Cross(v,w);
return P + v*t;
}
int main()
{
int n;
scanf("%d",&n);
printf("INTERSECTING LINES OUTPUT\n");
while(n--)
{
scanf("%lf %lf %lf %lf",&a.x, &a.y, &b.x, &b.y);
scanf("%lf %lf %lf %lf",&c.x, &c.y, &d.x, &d.y);
if(Cross(a - c, b - c) == && Cross(a - d, b - d) == )
printf("LINE\n");
else if(Cross(a - b, c- d) == )
printf("NONE\n");
else
{
Point p = GetLineIntersection(a, a-b, c, c-d);
printf("POINT %.2f %.2f\n",p.x,p.y);
}
}
printf("END OF OUTPUT\n");
return ;
}

POJ 1556 The Doors

题意:问你从(0,5) - > (10, 5)的最短路。

思路:枚举所有端点,如果确定和其他线段不规范相交,则加入这条路径,然后拿Floyd去跑最短路即可。

AC代码:

 #include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const double eps = 1e-;
const int maxn = 1e3 + ;
const double inf = 1e20;
struct Point{
double x, y;
Point(double _x = , double _y = ):x(_x),y(_y){}
};
typedef Point Vector;
Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x; }//²æ»ý
int dcmp(double x){
if(fabs(x) < eps) return ; else return x < ? - : ;
}
double distant(Point a, Point b){
double x = a.x - b.x;
double y = a.y - b.y;
return sqrt(x*x + y*y);
}
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)
{
double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1,a2 - b1);
return dcmp(c1)*dcmp(c2) < && dcmp(c3)*dcmp(c4) < ;
}
struct edge{
Point from, to;
edge(){}
edge(Point a, Point b){ from = a,to = b;}
};
Point p[maxn];
edge e[maxn];
double d[maxn][maxn];
int n, tot, cnt;
bool check(Point a, Point b)
{
for(int i = ;i < tot;i++)
if(SegmentProperIntersection(a, b, e[i].from, e[i].to))
{
return false;
} return true;
}
int main()
{
while(~scanf("%d",&n) && n != -)
{
tot = cnt = ;
double x, y1, y2, y3, y4;
p[cnt++] = Point(, );
for(int i = ;i < n;i++)
{
scanf("%lf%lf%lf%lf%lf",&x, &y1, &y2, &y3, &y4);
p[cnt++] = Point(x, y1);
p[cnt++] = Point(x, y2);
p[cnt++] = Point(x, y3);
p[cnt++] = Point(x, y4);
e[tot++] = edge(Point(x, ), Point(x, y1));
e[tot++] = edge(Point(x, y2), Point(x, y3));
e[tot++] = edge(Point(x, y4), Point(x, ));
}
p[cnt++] = Point(, );
for(int i = ;i < cnt;i++)
for(int j = ;j < cnt;j++)
d[i][j] = inf;
for(int i = ; i < cnt;i++)
{
for(int j = i + ;j < cnt;j ++)
{
if(fabs(p[i].x - p[j].x)< eps)continue;
if(check(p[i], p[j]))
{
d[i][j] = d[j][i] = distant(p[i], p[j]);
}
}
}
for(int k = ;k < cnt;k++)
for(int i = ;i < cnt;i++)
for(int j = ;j < cnt;j++)
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
printf("%.2f\n",d[][cnt - ]);
}
return ;
}

POJ 2653 Pick-up sticks

题意:筷子一根一根丢,问哪些筷子没被压着。

思路:所有和新加入的线段规范相交的线段标记,最后未标记的输出。

AC代码:

 #include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const double eps = 1e-;
const int maxn = 1e5 + ;
const double inf = 1e20;
struct Point{
double x, y;
Point(double _x = , double _y = ):x(_x),y(_y){}
};
typedef Point Vector;
Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x; }//²æ»ý
int dcmp(double x){
if(fabs(x) < eps) return ; else return x < ? - : ;
}
double distant(Point a, Point b){
double x = a.x - b.x;
double y = a.y - b.y;
return sqrt(x*x + y*y);
}
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)
{
double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1,a2 - b1);
return dcmp(c1)*dcmp(c2) < && dcmp(c3)*dcmp(c4) < ;
}
struct Line{
Point from, to;
Line(){}
Line(Point a, Point b){ from = a,to = b;}
};
Line line[maxn];
bool check(Line a, Line b)
{
return SegmentProperIntersection(a.from, a.to, b.from, b.to);
}
int vis[maxn];
int n, tot, cnt;
int main()
{
while(~scanf("%d",&n) && n)
{
double x1, y1, x2, y2;
for(int i = ;i < n;i++)
{
scanf("%lf %lf %lf %lf",&x1, &y1, &x2, &y2);
line[i] = Line( Point(x1, y1), Point(x2, y2) );
vis[i] = ;
}
for(int i = ;i < n;i++){
for(int j = i + ;j < n;j++)
{
if(check(line[i], line[j]))
{
vis[i] = ;break;
}
}
}
printf("Top sticks: ");
bool flag = true;
for(int i = ;i < n;i++)
{
if(!vis[i])
{
if(flag) flag = false;
else printf(", ");
printf("%d",i + );
}
}
printf(".\n");
}
return ;
}

POJ 1066 Treasure Hunt

题意:给你一个房间,房间内有很多墙,再给你个宝藏的坐标,你将从外面砸墙而入,问:你炸墙进去通过的最少的墙的1数目是多少。

思路:枚举线段的端点和宝藏位置的连线,看看和几个线段相交,要加上最外围的墙,所以ans从1开始。

AC代码:

 #include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const double eps = 1e-;
const int maxn = 1e5 + ;
const int inf = 0x3f3f3f3f;
struct Point{
double x, y;
Point(double _x = , double _y = ):x(_x),y(_y){}
};
typedef Point Vector;
Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x; }//²æ»ý
int dcmp(double x){
if(fabs(x) < eps) return ; else return x < ? - : ;
}
double distant(Point a, Point b){
double x = a.x - b.x;
double y = a.y - b.y;
return sqrt(x*x + y*y);
}
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)
{
double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1,a2 - b1);
return dcmp(c1)*dcmp(c2) < && dcmp(c3)*dcmp(c4) < ;
}
struct Line{
Point from, to;
Line(){}
Line(Point a, Point b){ from = a,to = b;}
};
Point p[maxn];
Line line[maxn];
int vis[maxn];
int n, tot, cnt;
int check(Point b, Point a)
{
int ans = ;
for(int i = ;i < tot;i++)
{
if(SegmentProperIntersection(line[i].from, line[i].to, b, a))
ans ++;
}
return ans;
}
int main()
{
while(~scanf("%d",&n))
{
if(n == )
{
printf("Number of doors = 1\n");return ;
}
double x1, x2, y1, y2;
double x, y;
tot = cnt = ;
int ans = inf;
for(int i = ;i < n;i++)
{
scanf("%lf %lf %lf %lf",&x1 ,&y1, &x2, &y2);
p[cnt++] = Point(x1, y1);
p[cnt++] = Point(x2, y2);
line[tot++] = Line(Point(x1, y1), Point(x2, y2));
}
scanf("%lf %lf",&x, &y);
Point A = Point(x, y);
for(int i = ;i < cnt;i++)
{
ans = min(ans, check(A, p[i]));
}
printf("Number of doors = %d\n",ans);
}
return ;
}

POJ 1410 Intersection

题意:问直线和矩形是否相交。

思路:这题有坑,这矩形居然是实的,所以要特判一些情况。

AC代码:

 #include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const double eps = 1e-;
const int maxn = 1e5 + ;
const int inf = 0x3f3f3f3f;
struct Point{
double x, y;
Point(double _x = , double _y = ):x(_x),y(_y){}
};
typedef Point Vector;
Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x; }//²æ»ý
double Dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; }//点积
int dcmp(double x){
if(fabs(x) < eps) return ; else return x < ? - : ;
}
double distant(Point a, Point b){
double x = a.x - b.x;
double y = a.y - b.y;
return sqrt(x*x + y*y);
}
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)
{
double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1,a2 - b1);
return dcmp(c1)*dcmp(c2) < && dcmp(c3)*dcmp(c4) < ;
}
struct Line{
Point from, to;
Line(){}
Line(Point a, Point b){ from = a,to = b;}
};
bool check(Line a, Line b){
return SegmentProperIntersection(a.from, a.to, b.from, b.to);
}
bool OnSegment(Point p, Point a1, Point a2){//判断端点在线段上
return dcmp(Cross(a1 - p, a2 - p)) == && dcmp(Dot(a1 - p,a2 - p)) < ;
}
bool check2(Point b, Line a){
return OnSegment(b, a.from, a.to);
}
int n;
int main()
{
scanf("%d",&n);
double x1, y1, x2, y2;
double x3, y3, x4, y4;
while(n--)
{
bool flag = false;
scanf("%lf %lf %lf %lf",&x1, &y1, &x2, &y2);
Point E = Point(x1, y1);
Point F = Point(x2, y2);
Line L = Line(E, F);
scanf("%lf %lf %lf %lf",&x3, &y3, &x4, &y4);
if(x3 > x4) swap(x3, x4);
if(y3 < y4) swap(y3, y4);
Point A = Point(x3, y3);
Point B = Point(x3, y4);
Point C = Point(x4, y4);
Point D = Point(x4, y3);
Line AB = Line(A, B);
Line CB = Line(C, B);
Line CD = Line(C, D);
Line AD = Line(A, D);
if(x1 >= x3 && x1 <= x4 && y1 <= y3 && y1 >= y4) flag = true;
if(check(AB, L) || check(CD, L) || check(AD, L) || check(CB, L))
flag = true;
if(check2(A, L) || check2(B, L) || check2(C, L) || check2(D, L))
flag = true;
if(check2(E, AB) || check2(E, CD) || check2(E, AD) || check2(E, CB))
flag = true;
if(check2(F, AB) || check2(F, CD) || check2(F, AD) || check2(F, CB))
flag = true;
if(flag) printf("T\n");
else printf("F\n");
}
return ;
}

POJ 1696 Space Ant

题意:一只蚂蚁,只会向左转,现在给出平面上很多个点,求解一种走法,能使得蚂蚁能经过的点最多,每个顶点该蚂蚁只能经过一次,且所行走的路线不能发生交叉.

思路:这题用极角排序,边排序边输出orz。

AC代码:

 #include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const double eps = 1e-;
const int maxn = 1e3+ ;
const int inf = 0x3f3f3f3f;
struct Point{
double x, y;
int num;
Point(double _x = , double _y = ):x(_x),y(_y){}
};
typedef Point Vector;
Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x; }//²æ»ý
double Dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; }//点积
int dcmp(double x){
if(fabs(x) < eps) return ; else return x < ? - : ;
}
double distant(Point a, Point b){
double x = a.x - b.x;
double y = a.y - b.y;
return sqrt(x*x + y*y);
}
Point p[maxn];
int pos;
bool cmp(const Point a, const Point b){
int temp = Cross(p[pos] - a,p[pos] - b);
if(temp > ) return true;
else if(temp == && distant(p[pos], a) < distant(p[pos], b))
return true;
return false;
}
int n;
int main()
{
int t;
scanf("%d",&t);
while (t--){
scanf("%d",&n);
for (int i = ; i < n; ++i) {
scanf("%d %lf %lf",&p[i].num, &p[i].x, &p[i].y);
if(p[i].y < p[].y || (p[i].y == p[].y && p[i].x < p[].x))
swap(p[i],p[]);
}
pos = ;
printf("%d",n);
for(int i = ;i < n;++i){
sort(p + i,p + n, cmp);
pos++;
}
for (int i = ; i < n; ++i) {
printf(" %d",p[i].num);
}
printf("\n");
}
return ;
}

POJ 3347 Kadj Squares

思路:这题在网上扒了一个不是几何的做法,具体看代码吧。

AC代码:

 #include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = ;
struct node{
int l, r, len;
};
node a[maxn];
int n;
int main()
{
while(~scanf("%d",&n) && n)
{
memset(a,,sizeof(a));
for(int i = ;i < n;i++)
{
scanf("%d",&a[i].len);
for(int j = ;j < i;j ++)
{
a[i].l = max(a[i].l, a[j].r - abs(a[i].len - a[j].len));
}
a[i].r = a[i].l + *a[i].len;
}
for(int i = ;i < n;i++)
{
for(int j = ;j < i;j ++)
{
if(a[i].l < a[j].r)
{
if(a[j].len < a[i].len) a[j].r = a[i].l;
else a[i].l = a[j].r;
}
}
}
bool flag = false;
for(int i = ;i < n;i++)
{
if(a[i].l < a[i].r)
{
if(!flag) printf("%d",i + ),flag = true;
else printf(" %d",i+);
}
}
printf("\n");
}
return ;
}

POJ 2826 An Easy Problem?!

题意:两根木棍,摆放的方式由题目给出,问接到雨水的量是多少。(注意是平面,只要考虑面积)

思路:这题不看题解真想不到,简直天坑,点题解一看图就懂了,太多特殊情况了。最后所有都特判了,结果答案还要加个eps才能过orz,醉了!

AC代码:

 #include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const double eps = 1e-;
int sgn(double x){
if(fabs(x) < eps) return ;
else return x < ? - : ;
}
struct Point{
double x, y;
Point(){}
Point(double _x, double _y){
x = _x, y = _y;
}
Point operator - (const Point &b){
return Point(x - b.x, y - b.y);
}
double operator * (const Point &b){
return x*b.x + y*b.y;
}
double operator ^ (const Point &b){
return x*b.y - y* b.x;
}
};
struct Line{
Point s, e;
Line(){}
Line(Point _s, Point _e){
s = _s, e = _e;
}
int segcrossing(Line v)
{
int d1 = sgn((e - s)^(v.s - s));
int d2 = sgn((e - s)^(v.e - s));
int d3 = sgn((v.e - v.s)^(s - v.s));
int d4 = sgn((v.e - v.s)^(e - v.s));
if( (d1^d2) == - && (d3^d4) == - )return ;
return
(d1 == && sgn((v.s - s)*(v.s - e)) <= ) ||
(d2 == && sgn((v.e - s)*(v.e - e)) <= ) ||
(d3 == && sgn((s - v.s)*(s - v.e)) <= ) ||
(d4 == && sgn((e - v.s)*(e - v.e)) <= );
}
Point crosspoint(Line v){
double a1 = (v.e - v.s)^(s - v.s);
double a2 = (v.e - v.s)^(e - v.s);
return Point((s.x*a2 - e.x*a1)/(a2 - a1),(s.y*a2 - e.y*a1)/(a2 - a1));
}
};
int main()
{
double x1, x2, x3, x4, y1, y2, y3, y4;
Line A, B;
int t;
scanf("%d",&t);
while(t--){
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
scanf("%lf%lf%lf%lf", &x3, &y3, &x4, &y4);
A = Line(Point(x1, y1),Point(x2, y2));
B = Line(Point(x3, y3),Point(x4, y4));
if(sgn(A.s.y - A.e.y) == || sgn(B.s.y - B.e.y) == )
{
printf("0.00\n");
continue;
}
if(sgn((A.s - A.e)^(B.s - B.e)) == )
{
printf("0.00\n");
continue;
}
//高的点放 s.y下面会用到
if(sgn(A.s.y - A.e.y) < ) swap(A.s, A.e);
if(sgn(B.s.y - B.e.y) < ) swap(B.s, B.e); if(A.segcrossing(B) == )
{
printf("0.00\n");
continue;
}
//口被封掉的情况
if(B.segcrossing(Line(A.s,Point(A.s.x,))) )
{
printf("0.00\n");
continue;
}
if(A.segcrossing(Line(B.s,Point(B.s.x,))) )
{
printf("0.00\n");
continue;
}
Point C = A.crosspoint(B);
//printf("%f %f",C.x,C.y);
double ans1,ans2;
Point D = A.crosspoint(Line(Point(,B.s.y),B.s));
//printf("%f %f",D.x,D.y);
ans1 = fabs( (B.s - C) ^ (D - C) )/2.0;
Point E = B.crosspoint(Line(Point(,A.s.y),A.s));
ans2 = fabs( (A.s - C) ^ (E - C) )/2.0;
double ans = min(ans1,ans2);
printf("%.2f\n",ans +eps);
}
return ;
}

POJ 1039 Pipe

题意:有一宽度为1的折线管道,上面顶点为(xi,yi),所对应的下面顶点为(xi,yi-1),假设管道都是不透明的,不反射的,光线从左边入口处的(x1,y1),(x1,y1-1)之间射入,向四面八方传播,求解光线最远能传播到哪里(取x坐标)或者是否能穿透整个管道。

思路:因为WA到自闭。于是改用kuangbin大佬的板子,于是就过了,orz!板子很重要。能到达最远的光线一定是某一上端点和某一下端点的连线,枚举判断。

AC代码:

 #include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const double eps = 1e-;
const int maxp = ;
int sgn(double x){
if(fabs(x) < eps) return ;
else return x < ? - : ;
}
struct Point{
double x, y;
Point(){}
Point(double _x, double _y){
x = _x, y = _y;
}
Point operator -(const Point &b)const{
return Point(x - b.x, y - b.y);
}
double operator *(const Point &b)const{
return x*b.x + y*b.y;
}
double operator ^(const Point &b)const{
return x*b.y - y*b.x;
}
bool operator == (Point b) const{
return sgn(x - b.x) == && sgn(y - b.y) == ;
}
bool operator < (Point b)const{
return sgn(x - b.x) == ? sgn(y - b.y < ) : x < b.x;
}
};
struct Line{
Point s, e;
Line(){}
Line(Point _s, Point _e){s = _s, e = _e;}
bool operator == (Line v){
return (s == v.s) && (e == v.e);
}
int linecrossing(Line v){
int d1 = sgn((e - s) ^ (v.s - s));
int d2 = sgn((e - s) ^ (v.e - s));
if( (d1 ^ d2) == -) return ;
else return (d1 == ) || (d2 == );
}
Point crosspoint(Line v){
double a1 = (v.e - v.s)^(s - v.s);
double a2 = (v.e - v.s)^(e - v.s);
return Point((s.x*a2 - e.x*a1)/(a2 - a1),(s.y*a2 - e.y*a1)/(a2 - a1));
}
};
Point up[maxp], down[maxp];
int main()
{
int n;
Line A;
while(~scanf("%d",&n) && n)
{
for(int i = ;i < n;i++)
{
scanf("%lf %lf",&up[i].x, &up[i].y);
down[i].x = up[i].x, down[i].y = up[i].y - ;
}
bool flag = false;
double ans = -100000000.0;
for(int i = ;i < n;i++)
{
for(int j = ;j < n;j++)
{
int k;
A = Line(up[i], down[j]);
for(k = ;k < n;k++){
if(!A.linecrossing(Line(up[k], down[k])) )
{
break;
}
}
if(k >= n){flag = true;break;}
if(k > max(i, j))
{
if(A.linecrossing(Line(up[k], up[k-])))
{
Point x = A.crosspoint(Line(up[k], up[k-]));
ans = max(ans,x.x);
}
if(A.linecrossing(Line(down[k], down[k-])))
{
Point x = A.crosspoint(Line(down[k], down[k-]));
ans = max(ans,x.x);
}
}
if(flag) break;
}
}
if(flag) printf("Through all the pipe.\n");
else printf("%.2f\n",ans + eps);
}
return ;
}

POJ 3449 Geometric Shapes

POJ 1584 A Round Peg in a Ground Hole

kuangbin专题十三-基础计算几何的更多相关文章

  1. kuangbin专题 数论基础 part1?

    线段树专题太难了,那我来做数学吧! 但数学太难了,我......(扯 这两天想了做了查了整理了几道数学. 除了一些进阶的知识,像莫比乌斯反演,杜教筛,min25学不会我跳了,一些基础的思维还是可以记录 ...

  2. [kuangbin]专题六 最小生成树 题解+总结

    kuangbin专题链接:https://vjudge.net/article/752 kuangbin专题十二 基础DP1 题解+总结:https://www.cnblogs.com/RioTian ...

  3. Kuangbin 带你飞-基础计算几何专题 题解

    专题基本全都是模版应用.贴一下模版 平面最近点对 const double INF = 1e16; ; struct Point { int x,y; int type; }; double dist ...

  4. 【kuangbin专题】计算几何_半平面交

    1.poj3335 Rotating Scoreboard 传送:http://poj.org/problem?id=3335 题意:就是有个球场,球场的形状是个凸多边形,然后观众是坐在多边形的边上的 ...

  5. 【kuangbin专题】计算几何_凸包

    1.poj1113 Wall 题目:http://poj.org/problem?id=1113 题意:用一条线把若干个点包起来,并且线距离任何一个点的距离都不小于r.求这条线的最小距离是多少? 分析 ...

  6. aria2 源码解析专题—— (一)基础架构

    此文章是这个专题的开篇,由于初入 C++ 的大门,所以想着拿个项目来看看,凑巧有点基础,又想学习一下在unix上的编程,所以就找了 aria2 这个库来看看源码,希望能学到一些东西. 言归正传,今天把 ...

  7. [原]最短路专题【基础篇】(updating...)

    hud1548 a strange lift  最短路/bfs  题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1548 题意:一个奇怪的电梯,每层楼的 ...

  8. R语言︱SNA-社会关系网络 R语言实现专题(基础篇)(一)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 笔者寄语:这里所有的应用代码都来自与igrap ...

  9. LightOJ 1062 - Crossed Ladders 基础计算几何

    http://www.lightoj.com/volume_showproblem.php?problem=1062 题意:问两条平行边间的距离,给出从同一水平面出发的两条相交线段长,及它们交点到水平 ...

随机推荐

  1. 使用python实现希尔、计数、基数排序

    希尔排序 希尔排序是一个叫希尔的数学家提出的一种优化版本的插入排序. 首先取一个整数d1=n//2,将元素分为d1个组,每组相邻元素之间的距离为d1,在各组内进行直接插入排序. 取第二个整数d2=d1 ...

  2. python学习笔记:目录结构

    "项目目录结构"其实也是属于"可读性和可维护性"的范畴. 目录组织方式 关于如何组织一个较好的Python工程目录结构,已经有一些得到了共识的目录结构.在Sta ...

  3. jQuery选择器中空格的问题再探究

    jQuery选择器的空格问题,看似很小,但是差之毫厘谬以千里,让人很是恼火,<锋利的jQuery>书中有个经典的例子,我这里也拷贝下来,再加点自己的想法 <html> < ...

  4. 利用docker搭建WordPress

    步骤一 创建mysql的容器 步骤二 创建wordpress的容器并链接mysql容器的数据库 创建mysql的容器 docker run -d --name mysql -v mysql-data: ...

  5. FrameWork内核解析之WindowManagerService(一)中篇

    阿里P7Android高级架构进阶视频免费学习请点击:https://space.bilibili.com/474380680 1.WMS概述 WMS是系统的其他服务,无论对于应用开发还是Framew ...

  6. LeetCode Array Easy 88. Merge Sorted Array

    Description Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted ar ...

  7. js 禁止右击保存图片,禁止拖拽图片

    禁止鼠标右键保存图片 <img src="" oncontextmenu="return false;"> 禁止鼠标拖动图片 <img src ...

  8. opensns学习

    根据ThinkPHP官方文档学习opensns框架 主要看了下opensns所用的单一入口模式的意义. 基础 opensns目录结构 index.php 入口文件 Application 应用目录(含 ...

  9. Bash: Removing leading zeroes from a variable

    old=" # sed removes leading zeroes from stdin new=$(echo $old | sed 's/^0*//')

  10. 笔记62 Spring Boot快速入门(二)

    SpringBoot部署 一.jar方式 1.首先安装maven. <1>下载最新的maven版本:https://maven.apache.org/download.cgi <2& ...