景驰无人驾驶 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 }