景驰无人驾驶 1024 编程邀请赛 B题 计算几何+裸二分匹配

暴力n2建边,然后跑二分图匹配,比赛时候写了一个BUG代码,调了比赛一个半小时,赛后半小时才过。

在check的时候,我是直接求出每个矩形四个顶点,然后矩形面积交求答案。

  1 #include <bits/stdc++.h>
  2 const long long mod = 1e9+7;
  3 const double ex = 1e-10;
  4 const double pi = acos(-1.0);
  5 #define inf 0x3f3f3f3f
  6 using namespace std;
  7 struct scana{
  8     int x,y,v,a,xita,w,l;
  9 }A[200];
 10 struct scanb{
 11     int x,y,xita,w,l;
 12 }B[200];
 13 /*
 14  * 多边形的交,多边形的边一定是要按逆时针方向给出
 15  * 还要判断是凸包还是凹包,调用相应的函数
 16  * 面积并,只要和面积减去交即可
 17  */
 18 const int maxn = 20;
 19 const double eps = 1e-6;
 20 int dcmp(double x)
 21 {
 22     if(x > eps) return 1;
 23     return x < -eps ? -1 : 0;
 24 }
 25 struct Point
 26 {
 27     double x, y;
 28 };
 29 double cross(Point a,Point b,Point c) ///叉积
 30 {
 31     return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
 32 }
 33 Point intersection(Point a,Point b,Point c,Point d)
 34 {
 35     Point p = a;
 36     double t =((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))/((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));
 37     p.x +=(b.x-a.x)*t;
 38     p.y +=(b.y-a.y)*t;
 39     return p;
 40 }
 41 //计算多边形面积
 42 double PolygonArea(Point p[], int n)
 43 {
 44     if(n < 3) return 0.0;
 45     double s = p[0].y * (p[n - 1].x - p[1].x);
 46     p[n] = p[0];
 47     for(int i = 1; i < n; ++ i)
 48         s += p[i].y * (p[i - 1].x - p[i + 1].x);
 49     return fabs(s * 0.5);
 50 }
 51 double CPIA(Point a[], Point b[], int na, int nb)//ConvexPolygonIntersectArea
 52 {
 53     Point p[20], tmp[20];
 54     int tn, sflag, eflag;
 55     a[na] = a[0], b[nb] = b[0];
 56     memcpy(p,b,sizeof(Point)*(nb + 1));
 57     for(int i = 0; i < na && nb > 2; i++)
 58     {
 59         sflag = dcmp(cross(a[i + 1], p[0],a[i]));
 60         for(int j = tn = 0; j < nb; j++, sflag = eflag)
 61         {
 62             if(sflag>=0) tmp[tn++] = p[j];
 63             eflag = dcmp(cross(a[i + 1], p[j + 1],a[i]));
 64             if((sflag ^ eflag) == -2)
 65                 tmp[tn++] = intersection(a[i], a[i + 1], p[j], p[j + 1]); ///求交点
 66         }
 67         memcpy(p, tmp, sizeof(Point) * tn);
 68         nb = tn, p[nb] = p[0];
 69     }
 70     if(nb < 3) return 0.0;
 71     return PolygonArea(p, nb);
 72 }
 73 double SPIA(Point a[], Point b[], int na, int nb)///SimplePolygonIntersectArea 调用此函数
 74 {
 75     int i, j;
 76     Point t1[4], t2[4];
 77     double res = 0, num1, num2;
 78     a[na] = t1[0] = a[0], b[nb] = t2[0] = b[0];
 79     for(i = 2; i < na; i++)
 80     {
 81         t1[1] = a[i-1], t1[2] = a[i];
 82         num1 = dcmp(cross(t1[1], t1[2],t1[0]));
 83         if(num1 < 0) swap(t1[1], t1[2]);
 84         for(j = 2; j < nb; j++)
 85         {
 86             t2[1] = b[j - 1], t2[2] = b[j];
 87             num2 = dcmp(cross(t2[1], t2[2],t2[0]));
 88             if(num2 < 0) swap(t2[1], t2[2]);
 89             res += CPIA(t1, t2, 3, 3) * num1 * num2;
 90         }
 91     }
 92     return res;
 93 }
 94 Point p1[maxn], p2[maxn];
 95 double a,b,c;
 96 double dis(double x1,double y1,double x2,double y2){
 97     return sqrt((x1-x2)*(x1-x2) + (y1 -y2)*(y1-y2));
 98 }
 99 bool check(int i,int j){
100 
101     double s1 = 1.0*A[i].l*A[i].w;
102     double s2 = 1.0*B[j].l*B[j].w;
103     double det = a*1.0*A[i].v + a*1.0*a*A[i].a/2;
104     double xita = A[i].xita*1.0/180*pi;
105     double x1 = A[i].x*1.0 + det * cos(xita);
106     double y1 = A[i].y*1.0 + det * sin(xita);
107     double x2 = B[j].x*1.0;
108     double y2 = B[j].y*1.0;
109 
110     double ss = sqrt(1.0*A[i].w * 1.0*A[i].w /4.0 + 1.0*A[i].l * 1.0*A[i].l /4.0);
111     double sxita = atan(A[i].w*1.0/A[i].l);
112 
113     p1[0].x = x1 + ss * cos(xita - sxita);
114     p1[0].y = y1 + ss * sin(xita - sxita);
115 
116     p1[1].x = x1 + ss * cos(xita + sxita);
117     p1[1].y = y1 + ss * sin(xita + sxita);
118 
119     p1[2].x = x1 - ss * cos(xita - sxita);
120     p1[2].y = y1 - ss * sin(xita - sxita);
121 
122     p1[3].x = x1 - ss * cos(xita + sxita);
123     p1[3].y = y1 - ss * sin(xita + sxita);
124 
125     xita = B[j].xita*1.0/180*pi;
126     ss = sqrt(1.0*B[j].w * 1.0*B[j].w /4.0 + 1.0*B[j].l * 1.0*B[j].l /4.0);
127     sxita = atan(B[j].w*1.0/B[j].l);
128 
129     p2[0].x = x2 + ss * cos(xita - sxita);
130     p2[0].y = y2 + ss * sin(xita - sxita);
131 
132     p2[1].x = x2 + ss * cos(xita + sxita);
133     p2[1].y = y2 + ss * sin(xita + sxita);
134 
135     p2[2].x = x2 - ss * cos(xita - sxita);
136     p2[2].y = y2 - ss * sin(xita - sxita);
137 
138     p2[3].x = x2 - ss * cos(xita + sxita);
139     p2[3].y = y2 - ss * sin(xita + sxita);
140     double Area = SPIA(p1, p2, 4, 4);
141     if (Area>=(s1+s2-Area) * b || dis(x1,y1,x2,y2) <= c){
142         return true;
143     }
144     return false;
145 }
146 const int MAXN=300;
147 int uN,vN;  //u,v数目
148 int g[MAXN][MAXN];//编号是0~n-1的
149 int linker[MAXN];
150 bool used[MAXN];
151 bool dfs(int u)
152 {
153     int v;
154     for(v=0;v<vN;v++)
155         if(g[u][v]&&!used[v])
156         {
157             used[v]=true;
158             if(linker[v]==-1||dfs(linker[v]))
159             {
160                 linker[v]=u;
161                 return true;
162             }
163         }
164     return false;
165 }
166 int hungary()
167 {
168     int res=0;
169     int u;
170     memset(linker,-1,sizeof(linker));
171     for(u=0;u<uN;u++)
172     {
173         memset(used,0,sizeof(used));
174         if(dfs(u))  res++;
175     }
176     return res;
177 }
178 int main()
179 {
180     int  T;
181     scanf("%d",&T);
182     while (T--){
183         int n,m;
184         scanf("%d%d",&n,&m);
185         cin >> a >> b >> c;
186         for (int i = 1; i<=n; i++){
187             scanf("%d%d%d%d%d%d%d",&A[i].x,&A[i].y,&A[i].v,&A[i].a,&A[i].xita,&A[i].l,&A[i].w);
188         }
189         for (int i = 1; i<=m; i++){
190             scanf("%d%d%d%d%d",&B[i].x,&B[i].y,&B[i].xita,&B[i].l,&B[i].w);
191         }
192         memset(g,0,sizeof(g));
193         uN = n;
194         vN = m;
195         for (int i = 1; i<=n;i++){
196             for (int j = 1; j<=m; j++){
197                 if (check(i,j)){
198                     g[i-1][j-1] = 1;
199                 }
200             }
201         }
202         int ans = hungary();
203         cout << ans << endl;
204     }
205     return 0;
206 }
View Code

 

转载于:https://www.cnblogs.com/HITLJR/p/7726238.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值