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

时间:2023-02-10 18:53:13

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

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

景驰无人驾驶 1024 编程邀请赛 B题 计算几何+裸二分匹配景驰无人驾驶 1024 编程邀请赛 B题 计算几何+裸二分匹配
  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