2012 ACM/ICPC 亚洲区 金华站
题目链接 2012金华区域赛
Problem A
按a/b从小到大的顺序排队进行体检即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cstring> 7 #include<string> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #include<queue> 12 using namespace std; 13 typedef long long ll; 14 const ll mod=365*24*60*60; 15 struct ss 16 { 17 int x,y; 18 double p; 19 }; 20 ss a[100010]; 21 int n; 22 inline bool cmp(ss a,ss b) 23 { 24 return a.p<b.p; 25 } 26 int main() 27 { 28 while (~scanf("%d",&n)) 29 { 30 if (n==0) break; 31 int i; 32 for (i=1;i<=n;i++) 33 { 34 scanf("%d%d",&a[i].x,&a[i].y); 35 a[i].p=a[i].x*1.0/a[i].y; 36 } 37 sort(a+1,a+n+1,cmp); 38 ll sum=0; 39 for (i=1;i<=n;i++) 40 sum=((sum+sum*a[i].y%mod)%mod+a[i].x)%mod; 41 printf("%lld\n",sum); 42 } 43 return 0; 44 }
Problem B
Problem C
先把所有的坐标离散化
将起点、终点和所有矩形的点
每个点4个方向,拆成4个点
然后如果一个点的一个方向能经过一次转弯直接到另一个点
就连一条边
建完图后用SPFA求最短路即可
但本题细节较多
最难处理的是墙角的转角情况
可以先把所有墙角预处理出来
一共8种情况
其他的就离散化后坐标乘2
然后用个数组标记每个点会经过几次
如果点已经在矩形内部
就直接置为经过2次
然后在判断时 判断路线上有没有经过2次以上的点
或者恰有一个墙角点但可以转弯
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cstring> 7 #include<string> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #include<queue> 12 using namespace std; 13 #define y1 hjhk 14 #define y2 mhgu 15 const int inf=(1<<31)-1; 16 struct Hash : vector<int> { 17 void prepare() { 18 sort(begin(), end()); 19 erase(unique(begin(), end()), end()); 20 } 21 int get(int x) { 22 return lower_bound(begin(), end(), x)-begin()+1; 23 } 24 } has; 25 int x1,y1,x2,y2,n; 26 struct ss 27 { 28 int x1,y1,x2,y2; 29 }; 30 ss a[51]; 31 int dis[1500][4]; 32 int can[1500][1500]; 33 bool mop[1500][1500][4][4]; 34 queue<pair<int,int>> q; 35 bool vis[1500][4]; 36 pair<int,int> det[1500]; 37 void relax(pair<int,int> from,int x2,int y2,int ndis) 38 { 39 //cout<<from.first<<" "<<from.second<<" "<<x2<<" "<<y2<<" "<<ndis<<endl; 40 if (ndis<dis[x2][y2]) 41 { 42 dis[x2][y2]=ndis; 43 //cout<<from.first<<" "<<from.second<<" "<<x2<<" "<<y2<<" "<<ndis<<endl; 44 if (!vis[x2][y2]) 45 { 46 q.push({x2,y2}); 47 vis[x2][y2]=true; 48 } 49 } 50 } 51 int main() 52 { 53 //freopen("4444.in","r",stdin); 54 //freopen("out.txt","w",stdout); 55 while (~scanf("%d%d%d%d",&x1,&y1,&x2,&y2)) 56 { 57 if (x1==0&&y1==0&&x2==0&&y2==0) return 0; 58 scanf("%d",&n); 59 int i,j; 60 for (i=1;i<=n;i++) 61 { 62 scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2); 63 if (a[i].x1>a[i].x2) 64 swap(a[i].x1,a[i].x2); 65 if (a[i].y1>a[i].y2) 66 swap(a[i].y1,a[i].y2); 67 } 68 has.clear(); 69 has.push_back(x1); 70 has.push_back(x2); 71 for (i=1;i<=n;i++) 72 { 73 has.push_back(a[i].x1); 74 has.push_back(a[i].x2); 75 } 76 has.prepare(); 77 x1=has.get(x1)*2; 78 x2=has.get(x2)*2; 79 for (i=1;i<=n;i++) 80 { 81 a[i].x1=has.get(a[i].x1)*2; 82 a[i].x2=has.get(a[i].x2)*2; 83 } 84 has.clear(); 85 has.push_back(y1); 86 has.push_back(y2); 87 for (i=1;i<=n;i++) 88 { 89 has.push_back(a[i].y1); 90 has.push_back(a[i].y2); 91 } 92 has.prepare(); 93 y1=has.get(y1)*2; 94 y2=has.get(y2)*2; 95 for (i=1;i<=n;i++) 96 { 97 a[i].y1=has.get(a[i].y1)*2; 98 a[i].y2=has.get(a[i].y2)*2; 99 } 100 //cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl; 101 //for (i=1;i<=n;i++) 102 // printf("%d %d %d %d\n",a[i].x1,a[i].y1,a[i].x2,a[i].y2); 103 memset(mop,false,sizeof(mop)); 104 for (i=1;i<=n;i++) 105 for (j=1;j<=n;j++) 106 if (i!=j) 107 { 108 if (a[i].x2==a[j].x1&&a[i].y1<=a[j].y1) 109 { 110 mop[a[j].x1][a[j].y1][1][2]=true; 111 mop[a[j].x1][a[j].y1][0][3]=true; 112 //cout<<a[j].x1<<" "<<a[j].y1<<" "<<1<<" "<<2<<endl; 113 114 } 115 if (a[i].y2==a[j].y1&&a[i].x2<=a[j].x2) 116 { 117 mop[a[i].x2][a[i].y2][1][2]=true; 118 mop[a[i].x2][a[i].y2][0][3]=true; 119 //cout<<a[i].x2<<" "<<a[i].y2<<" "<<1<<" "<<2<<endl; 120 } 121 if (a[i].x2==a[j].x1&&a[i].y2<=a[j].y2) 122 { 123 mop[a[i].x2][a[i].y2][2][1]=true; 124 mop[a[i].x2][a[i].y2][3][0]=true; 125 //cout<<a[i].x2<<" "<<a[i].y2<<" "<<2<<" "<<1<<endl; 126 } 127 if (a[i].y2==a[j].y1&&a[i].x1<=a[j].x1) 128 { 129 mop[a[j].x1][a[j].y1][2][1]=true; 130 mop[a[j].x1][a[j].y1][3][0]=true; 131 //cout<<a[j].x1<<" "<<a[j].y1<<" "<<2<<" "<<1<<endl; 132 } 133 if (a[i].x2==a[j].x1&&a[i].y1>=a[j].y1) 134 { 135 mop[a[i].x2][a[i].y1][1][0]=true; 136 mop[a[i].x2][a[i].y1][2][3]=true; 137 //cout<<a[i].x2<<" "<<a[i].y1<<" "<<1<<" "<<0<<endl; 138 } 139 if (a[i].y2==a[j].y1&&a[i].x1>=a[j].x1) 140 { 141 mop[a[i].x1][a[i].y2][1][0]=true; 142 mop[a[i].x1][a[i].y2][2][3]=true; 143 //cout<<a[i].x1<<" "<<a[i].y2<<" "<<1<<" "<<0<<endl; 144 } 145 if (a[i].y2==a[j].y1&&a[i].x2>=a[j].x2) 146 { 147 mop[a[j].x2][a[j].y1][0][1]=true; 148 mop[a[j].x2][a[j].y1][3][2]=true; 149 //cout<<a[j].x2<<" "<<a[j].y1<<" "<<0<<" "<<1<<endl; 150 } 151 if (a[i].x2==a[j].x2&&a[i].y2>=a[j].y2) 152 { 153 mop[a[j].x1][a[j].y2][0][1]=true; 154 mop[a[j].x1][a[j].y2][3][2]=true; 155 //cout<<a[j].x1<<" "<<a[j].y2<<" "<<0<<" "<<1<<endl; 156 } 157 } 158 memset(can,0,sizeof(can)); 159 //cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl; 160 for (i=1;i<=n;i++) 161 { 162 for (int x=a[i].x1;x<=a[i].x2;x++) 163 for (int y=a[i].y1;y<=a[i].y2;y++) 164 { 165 can[x][y]++; 166 if (x!=a[i].x1&&x!=a[i].x2&&y!=a[i].y1&&y!=a[i].y2) 167 { 168 can[x][y]=2; 169 //if (x==11&&y==60) 170 // cout<<a[i].x1<<" "<<a[i].x2<<" "<<a[i].y1<<" "<<a[i].y2<<endl; 171 } 172 if (can[x][y]>2) can[x][y]=2; 173 //cout<<x<<" "<<y<<" "<<can[x][y]<<endl; 174 } 175 } 176 for (i=1;i<=n;i++) 177 for (j=1;j<=n;j++) 178 if (i!=j) 179 { 180 if (a[i].x2==a[j].x1&&a[i].y1==a[j].y1) can[a[i].x2][a[i].y1]=1; 181 if (a[i].x2==a[j].x1&&a[i].y2==a[j].y2) can[a[i].x2][a[i].y2]=1; 182 if (a[i].y2==a[j].y1&&a[i].x1==a[j].x1) can[a[i].x1][a[i].y2]=1; 183 if (a[i].y2==a[j].y1&&a[i].x2==a[j].x2) can[a[i].x2][a[i].y2]=1; 184 } 185 int cnt=0; 186 det[0].first=x1; 187 det[0].second=y1; 188 for (i=1;i<=n;i++) 189 { 190 det[++cnt].first=a[i].x1; 191 det[cnt].second=a[i].y1; 192 det[++cnt].first=a[i].x1; 193 det[cnt].second=a[i].y2; 194 det[++cnt].first=a[i].x2; 195 det[cnt].second=a[i].y1; 196 det[++cnt].first=a[i].x2; 197 det[cnt].second=a[i].y2; 198 } 199 det[++cnt].first=x2; 200 det[cnt].second=y2; 201 for (i=0;i<=cnt;i++) 202 dis[i][0]=dis[i][1]=dis[i][2]=dis[i][3]=inf; 203 dis[0][0]=0; 204 dis[0][1]=0; 205 dis[0][2]=0; 206 dis[0][3]=0; 207 memset(vis,false,sizeof(vis)); 208 vis[0][0]=true; 209 vis[0][1]=true; 210 vis[0][2]=true; 211 vis[0][3]=true; 212 while (!q.empty()) q.pop(); 213 q.push({0,0}); 214 q.push({0,1}); 215 q.push({0,2}); 216 q.push({0,3}); 217 while (!q.empty()) 218 { 219 pair<int,int> x=q.front(); 220 q.pop(); 221 vis[x.first][x.second]=false; 222 //cout<<det[x.first].first<<" "<<det[x.first].second<<endl; 223 //cout<<x.second<<endl; 224 //cout<< dis[x.first][x.second]<<endl; 225 for (i=0;i<=cnt;i++) 226 if (i!=x.first) 227 { 228 int x1=det[x.first].first; 229 int y1=det[x.first].second; 230 int x2=det[i].first; 231 int y2=det[i].second; 232 //cout<<i<<" "<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl; 233 if (x.second==3) 234 { 235 if (x2==x1&&y2<y1) 236 { 237 bool fg=true; 238 for (int y=y2;y<=y1;y++) 239 if (can[x1][y]==2) 240 { 241 fg=false; 242 break; 243 } 244 if (fg) 245 relax(x,i,3,dis[x.first][x.second]); 246 } 247 else if (x2<x1&&y2<y1) 248 { 249 int fg=0; 250 for (int y=y2;y<=y1;y++) 251 if (can[x1][y]==2) 252 { 253 fg++; 254 } 255 for (int x=x2;x<=x1;x++) 256 if (can[x][y2]==2) 257 { 258 fg++; 259 } 260 if (fg==0||(fg==2&&can[x1][y2]==2&&mop[x1][y2][3][0])) 261 relax(x,i,0,dis[x.first][x.second]+1); 262 } 263 else if (x2>x1&&y2<y1) 264 { 265 int fg=0; 266 for (int y=y2;y<=y1;y++) 267 if (can[x1][y]==2) 268 { 269 fg++; 270 //break; 271 } 272 for (int x=x1;x<=x2;x++) 273 if (can[x][y2]==2) 274 { 275 fg++; 276 //break; 277 } 278 if (fg==0||(fg==2&&can[x1][y2]==2&&mop[x1][y2][3][2])) 279 relax(x,i,2,dis[x.first][x.second]+1); 280 } 281 relax(x,x.first,2,dis[x.first][x.second]+1); 282 relax(x,x.first,0,dis[x.first][x.second]+1); 283 } 284 else if (x.second==0) 285 { 286 if (x2<x1&&y2==y1) 287 { 288 bool fg=true; 289 for (int x=x2;x<=x1;x++) 290 if (can[x][y2]==2) 291 { 292 fg=false; 293 break; 294 } 295 if (fg) 296 relax(x,i,0,dis[x.first][x.second]); 297 } 298 else if (x2<x1&&y2<y1) 299 { 300 int fg=0; 301 for (int y=y2;y<=y1;y++) 302 if (can[x2][y]==2) 303 { 304 fg++; 305 //break; 306 } 307 for (int x=x2;x<=x1;x++) 308 if (can[x][y1]==2) 309 { 310 fg++; 311 //break; 312 } 313 if (fg==0||(fg==2&&can[x2][y1]==2&&mop[x2][y1][0][3])) 314 relax(x,i,3,dis[x.first][x.second]+1); 315 } 316 else if (x2<x1&&y2>y1) 317 { 318 int fg=0; 319 for (int y=y1;y<=y2;y++) 320 if (can[x2][y]==2) 321 { 322 fg++; 323 //break; 324 } 325 for (int x=x2;x<=x1;x++) 326 if (can[x][y1]==2) 327 { 328 fg++; 329 //break; 330 } 331 if (fg==0||(fg==2&&can[x2][y1]==2&&mop[x2][y1][0][1])) 332 relax(x,i,1,dis[x.first][x.second]+1); 333 } 334 relax(x,x.first,1,dis[x.first][x.second]+1); 335 relax(x,x.first,3,dis[x.first][x.second]+1); 336 337 } 338 else if (x.second==1) 339 { 340 if (x2==x1&&y2>y1) 341 { 342 bool fg=true; 343 for (int y=y1;y<=y2;y++) 344 if (can[x2][y]==2) 345 { 346 fg=false; 347 break; 348 } 349 if (fg) 350 relax(x,i,1,dis[x.first][x.second]); 351 } 352 else if (x2<x1&&y2>y1) 353 { 354 int fg=0; 355 for (int y=y1;y<=y2;y++) 356 if (can[x1][y]==2) 357 { 358 fg++; 359 //break; 360 } 361 for (int x=x2;x<=x1;x++) 362 if (can[x][y2]==2) 363 { 364 fg++; 365 //break; 366 } 367 if (fg==0||(fg==2&&can[x1][y2]==2&&mop[x1][y2][1][0])) 368 relax(x,i,0,dis[x.first][x.second]+1); 369 } 370 else if (x2>x1&&y2>y1) 371 { 372 int fg=0; 373 for (int y=y1;y<=y2;y++) 374 if (can[x1][y]==2) 375 { 376 fg++; 377 //break; 378 } 379 for (int x=x1;x<=x2;x++) 380 if (can[x][y2]==2) 381 { 382 fg++; 383 //break; 384 } 385 if (fg==0||(fg==2&&can[x1][y2]==2&&mop[x1][y2][1][2])) 386 relax(x,i,2,dis[x.first][x.second]+1); 387 } 388 relax(x,x.first,2,dis[x.first][x.second]+1); 389 relax(x,x.first,0,dis[x.first][x.second]+1); 390 391 } 392 else if (x.second==2) 393 { 394 if (x2>x1&&y2==y1) 395 { 396 bool fg=true; 397 for (int x=x1;x<=x2;x++) 398 if (can[x][y2]==2) 399 { 400 //cout<<x<<" "<<y2<<endl; 401 fg=false; 402 break; 403 } 404 //cout<<fg<<" "<<cnt<<" "<<i<<endl; 405 if (fg) 406 relax(x,i,2,dis[x.first][x.second]); 407 } 408 else if (x2>x1&&y2<y1) 409 { 410 int fg=0; 411 for (int y=y2;y<=y1;y++) 412 if (can[x2][y]==2) 413 { 414 fg++; 415 //break; 416 } 417 for (int x=x1;x<=x2;x++) 418 if (can[x][y1]==2) 419 { 420 fg++; 421 //break; 422 } 423 if (fg==0||(fg==2&&can[x2][y1]==2&&mop[x2][y1][2][3])) 424 relax(x,i,3,dis[x.first][x.second]+1); 425 } 426 else if (x2>x1&&y2>y1) 427 { 428 int fg=0; 429 for (int y=y1;y<=y2;y++) 430 if (can[x2][y]==2) 431 { 432 fg++; 433 //break; 434 } 435 for (int x=x1;x<=x2;x++) 436 if (can[x][y1]==2) 437 { 438 fg++; 439 //break; 440 } 441 if (fg==0||(fg==2&&can[x2][y1]==2&&mop[x2][y1][2][1])) 442 relax(x,i,1,dis[x.first][x.second]+1); 443 } 444 relax(x,x.first,1,dis[x.first][x.second]+1); 445 relax(x,x.first,3,dis[x.first][x.second]+1); 446 } 447 } 448 } 449 int ans=inf; 450 ans=min(dis[cnt][0],ans); 451 ans=min(dis[cnt][1],ans); 452 ans=min(dis[cnt][2],ans); 453 ans=min(dis[cnt][3],ans); 454 if (ans==inf) puts("-1"); 455 else printf("%d\n",ans); 456 } 457 return 0; 458 }
Problem D
直接把180度分成3000分然后枚举取最小值即可。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) const double d = 3000; const double pi = acos(-1.0); const double g = 9.8000000; const int N = 2003; double v[N]; double l1, r1, l2, r2; int n; double h; int ans = 0; int now; int solve(double ap){ int ret = 0; rep(i, 1, n){ double now; now = sqrt(v[i] * v[i] * sin(ap) * sin(ap) + 2 * h * g); now = (now - v[i] * sin(ap)) / g * v[i] * cos(ap); if (now >= l2 && now <= r2) return -1; if (now >= l1 && now <= r1) ++ret; } return ret; } int main(){ while (~scanf("%d", &n), n){ ans = 0; scanf("%lf%lf%lf%lf%lf", &h, &l1, &r1, &l2, &r2); rep(i, 1, n) scanf("%lf", v + i); for (double i = -0.5 * pi; i <= 0.5 * pi; i += (pi / d)){ now = solve(i); if (~now) ans = max(ans, now); } now = solve(-0.5 * pi); if (~now) ans = max(ans, now); now = solve(0); if (~now) ans = max(ans, now); now = solve(0.5 * pi); if (~now) ans = max(ans, now); printf("%d\n", ans); } return 0; }
Problem E
Problem F
分解了十几项发现
$f_{x} = g_{a_{1}} * g_{a_{2}} * ... * g_{a_{m}}$,m为x的约数个数。
$a_{1},a_{2},...,a_{m}$分别为x的约数。
我们预处理出$g_{x},g_{x} = f_{x} / g_{a_{1}} / g_{a_{2}} / ... / g_{a_{m-1}}$
然后就可以计算答案了。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) const int N = 2200; vector <int> c[N]; struct dxs{ int l; int d[N]; dxs(){ memset(d, 0, sizeof d); l = 1;} } a[N]; int n; inline dxs chu(dxs a, dxs b){ dxs ret; ret.l = a.l - b.l + 1; memset(ret.d, 0, sizeof ret.d); dec(i, a.l - 1, b.l - 1){ int tt = a.d[i] / b.d[b.l - 1]; if (tt != 0){ rep(j, 0, b.l - 1){ a.d[i - j] -= tt * b.d[b.l - 1 - j]; } ret.d[i - b.l + 1] = tt; } } return ret; } bool cmp(int i, int j){ if (a[i].l != a[j].l) return a[i].l < a[j].l; dec(k, a[i].l - 1, 0) if(a[i].d[k] != a[j].d[k]) { if(abs(a[i].d[k]) == abs(a[j].d[k])) return a[i].d[k] < 0; else return abs(a[i].d[k]) < abs(a[j].d[k]); } return false; } void print(dxs a){ putchar('('); dec(i, a.l - 1, 0) if (a.d[i] != 0){ if (i == 0){ if (a.d[i] > 0) putchar('+'); printf("%d", a.d[i]); } else{ if (a.d[i] > 0 && i != a.l - 1) putchar('+'); if (a.d[i] == -1) putchar('-'); if (abs(a.d[i]) != 1) printf("%d", a.d[i]); if (i > 1) printf("x^%d", i); else putchar('x'); } } putchar(')'); } int main(){ rep(i, 2, 1100){ rep(j, 1, i) if (i % j == 0) c[i].push_back(j); } a[1].l = 2; a[1].d[0] = -1, a[1].d[1] = 1; rep(i, 2, 1100){ a[i].d[0] = -1; a[i].d[i] = 1; a[i].l = i + 1; a[i] = chu(a[i], a[1]); rep(j, 2, i - 1) if (i % j == 0) a[i] = chu(a[i], a[j]); } rep(i, 2, 1100) sort(c[i].begin(), c[i].end(), cmp); while (~scanf("%d", &n), n){ if (n == 1){ puts("x-1"); continue; } for (auto u : c[n]) print(a[u]); putchar(10); } return 0; }
Problem G
Problem H
先求出三维的凸包
然后枚举每个面作为底面
求出旋转后所有点的坐标
最后求出底面二维凸包的面积即可
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 #define eps 1e-7 6 using namespace std; 7 const double inf=0x3f3f3f3f; 8 const int MAXV=80; 9 const double EPS = 1e-9; 10 const double pi=acos(-1.0); 11 //三维点 12 struct pt { 13 double x, y, z; 14 pt() {} 15 pt(double _x, double _y, double _z): x(_x), y(_y), z(_z) {} 16 pt operator - (const pt p1) { 17 return pt(x - p1.x, y - p1.y, z - p1.z); 18 } 19 pt operator + (const pt p1) { 20 return pt(x + p1.x, y + p1.y, z + p1.z); 21 } 22 pt operator *(const pt p){ 23 return pt(y*p.z-z*p.y,z*p.x-x*p.z, x*p.y-y*p.x); 24 } 25 pt operator *(double d) 26 { 27 return pt(x*d,y*d,z*d); 28 } 29 30 pt operator / (double d) 31 { 32 return pt(x/d,y/d,z/d); 33 } 34 double operator ^ (pt p) { 35 return x*p.x+y*p.y+z*p.z; //点乘 36 } 37 double len(){ 38 return sqrt(x*x+y*y+z*z); 39 } 40 }; 41 struct pp{ 42 double x,y; 43 pp(){} 44 pp(double x,double y):x(x),y(y){} 45 }; 46 struct _3DCH { 47 struct fac { 48 int a, b, c; //表示凸包一个面上三个点的编号 49 bool ok; //表示该面是否属于最终凸包中的面 50 }; 51 52 int n; //初始点数 53 pt P[MAXV]; //初始点 54 55 int cnt; //凸包表面的三角形数 56 fac F[MAXV*8]; //凸包表面的三角形 57 58 int to[MAXV][MAXV]; 59 60 pt Cross3(pt a,pt p){ 61 return pt(a.y*p.z-a.z*p.y, a.z*p.x-a.x*p.z, a.x*p.y-a.y*p.x); //叉乘 62 } 63 double vlen(pt a) { 64 return sqrt(a.x*a.x+a.y*a.y+a.z*a.z); //向量长度 65 } 66 double area(pt a, pt b, pt c) { 67 return vlen(Cross3((b-a),(c-a))); //三角形面积*2 68 } 69 double volume(pt a, pt b, pt c, pt d) { 70 return Cross3((b-a),(c-a))^(d-a); //四面体有向体积*6 71 } 72 //三维点积 73 double Dot3( pt u, pt v ) 74 { 75 return u.x * v.x + u.y * v.y + u.z * v.z; 76 } 77 78 //平面的法向量 79 pt pvec(pt a,pt b,pt c) 80 { 81 return (Cross3((a-b),(b-c))); 82 } 83 //点到面的距离 84 double Dis(pt a,pt b,pt c,pt d) 85 { 86 return fabs(pvec(a,b,c)^(d-a))/vlen(pvec(a,b,c)); 87 } 88 //正:点在面同向 89 double ptof(pt &p, fac &f) { 90 pt m = P[f.b]-P[f.a], n = P[f.c]-P[f.a], t = p-P[f.a]; 91 return Cross3(m , n) ^ t; 92 } 93 94 void deal(int p, int a, int b) { 95 int f = to[a][b]; 96 fac add; 97 if (F[f].ok) { 98 if (ptof(P[p], F[f]) > eps) 99 dfs(p, f); 100 else { 101 add.a = b, add.b = a, add.c = p, add.ok = 1; 102 to[p][b] = to[a][p] = to[b][a] = cnt; 103 F[cnt++] = add; 104 } 105 } 106 } 107 108 void dfs(int p, int cur) { 109 F[cur].ok = 0; 110 deal(p, F[cur].b, F[cur].a); 111 deal(p, F[cur].c, F[cur].b); 112 deal(p, F[cur].a, F[cur].c); 113 } 114 115 bool same(int s, int t) { 116 pt &a = P[F[s].a], &b = P[F[s].b], &c = P[F[s].c]; 117 return fabs(volume(a, b, c, P[F[t].a])) < eps && fabs(volume(a, b, c, P[F[t].b])) < eps && fabs(volume(a, b, c, P[F[t].c])) < eps; 118 } 119 120 //构建三维凸包 121 void construct() { 122 cnt = 0; 123 if (n < 4) 124 return; 125 126 /*********此段是为了保证前四个点不公面,若已保证,可去掉********/ 127 bool sb = 1; 128 //使前两点不公点 129 for (int i = 1; i < n; i++) { 130 if (vlen(P[0] - P[i]) > eps) { 131 swap(P[1], P[i]); 132 sb = 0; 133 break; 134 } 135 } 136 if (sb)return; 137 138 sb = 1; 139 //使前三点不公线 140 for (int i = 2; i < n; i++) { 141 if (vlen(Cross3((P[0] - P[1]) , (P[1] - P[i]))) > eps) { 142 swap(P[2], P[i]); 143 sb = 0; 144 break; 145 } 146 } 147 if (sb)return; 148 149 sb = 1; 150 //使前四点不共面 151 for (int i = 3; i < n; i++) { 152 if (fabs(Cross3((P[0] - P[1]) , (P[1] - P[2])) ^ (P[0] - P[i])) > eps) { 153 swap(P[3], P[i]); 154 sb = 0; 155 break; 156 } 157 } 158 if (sb)return; 159 /*********此段是为了保证前四个点不公面********/ 160 161 162 fac add; 163 for (int i = 0; i < 4; i++) { 164 add.a = (i+1)%4, add.b = (i+2)%4, add.c = (i+3)%4, add.ok = 1; 165 if (ptof(P[i], add) > 0) 166 swap(add.b, add.c); 167 to[add.a][add.b] = to[add.b][add.c] = to[add.c][add.a] = cnt; 168 F[cnt++] = add; 169 } 170 171 for (int i = 4; i < n; i++) { 172 for (int j = 0; j < cnt; j++) { 173 if (F[j].ok && ptof(P[i], F[j]) > eps) { 174 dfs(i, j); 175 break; 176 } 177 } 178 } 179 int tmp = cnt; 180 cnt = 0; 181 for (int i = 0; i < tmp; i++) { 182 if (F[i].ok) { 183 F[cnt++] = F[i]; 184 } 185 } 186 } 187 188 //表面积 189 double area() { 190 double ret = 0.0; 191 for (int i = 0; i < cnt; i++) { 192 ret += area(P[F[i].a], P[F[i].b], P[F[i].c]); 193 } 194 return ret / 2.0; 195 } 196 197 //体积 198 double volume() { 199 pt O(0, 0, 0); 200 double ret = 0.0; 201 for (int i = 0; i < cnt; i++) { 202 ret += volume(O, P[F[i].a], P[F[i].b], P[F[i].c]); 203 } 204 return fabs(ret / 6.0); 205 } 206 207 //表面三角形数 208 int facetCnt_tri() { 209 return cnt; 210 } 211 212 //表面多边形数 213 int facetCnt() { 214 int ans = 0; 215 for (int i = 0; i < cnt; i++) { 216 bool nb = 1; 217 for (int j = 0; j < i; j++) { 218 if (same(i, j)) { 219 nb = 0; 220 break; 221 } 222 } 223 ans += nb; 224 } 225 return ans; 226 } 227 pt centroid(){ 228 pt ans(0,0,0),o(0,0,0); 229 double all=0; 230 for(int i=0;i<cnt;i++) 231 { 232 double vol=volume(o,P[F[i].a],P[F[i].b],P[F[i].c]); 233 ans=ans+(o+P[F[i].a]+P[F[i].b]+P[F[i].c])/4.0*vol; 234 all+=vol; 235 } 236 ans=ans/all; 237 return ans; 238 } 239 double res(){ 240 pt a=centroid(); 241 double _min=1e10; 242 for(int i=0;i<cnt;++i){ 243 double now=Dis(P[F[i].a],P[F[i].b],P[F[i].c],a); 244 _min=min(_min,now); 245 } 246 return _min; 247 } 248 double ptoface(pt p,int i) 249 { 250 return fabs(volume(P[F[i].a],P[F[i].b],P[F[i].c],p)/vlen((P[F[i].b]-P[F[i].a])*(P[F[i].c]-P[F[i].a]))); 251 } 252 }lou; 253 bool mult(pp sp,pp ep,pp op){ 254 return (sp.x-op.x)*(ep.y-op.y)>=(ep.x-op.x)*(sp.y-op.y); 255 } 256 double Cross(pp a,pp b,pp c){ 257 return (c.x-a.x)*(b.y-a.y) - (b.x-a.x)*(c.y-a.y); 258 } 259 260 bool cmp(pp a,pp b){ 261 if(a.y==b.y)return a.x<b.x; 262 return a.y<b.y; 263 } 264 int n,res[60],top; 265 pp ps[60]; 266 void Graham(){ 267 int len; 268 n=lou.n; 269 top=1; 270 sort(ps,ps+n,cmp); 271 if(n==0)return;res[0]=0; 272 if(n==1)return;res[1]=1; 273 if(n==2)return;res[2]=2; 274 for(int i=2;i<n;i++){ 275 while(top&&mult(ps[i],ps[res[top]],ps[res[top-1]])) 276 top--; 277 res[++top]=i; 278 } 279 len=top; 280 res[++top]=n-2; 281 for(int i=n-3;i>=0;i--){ 282 while(top!=len&&mult(ps[i],ps[res[top]],ps[res[top-1]]))top--; 283 res[++top]=i; 284 } 285 } 286 inline pt get_point(pt st,pt ed,pt tp) 287 { 288 double t1=(tp-st)^(ed-st); 289 double t2=(ed-st)^(ed-st); 290 double t=t1/t2; 291 pt ans=st + ((ed-st)*t); 292 return ans; 293 } 294 inline double dist(pt st,pt ed) 295 { 296 return sqrt((ed-st)^(ed-st)); 297 } 298 pp rotate(pt st,pt ed,pt tp,double A) 299 { 300 pt root=get_point(st,ed,tp); 301 pt e=(ed-st)/dist(ed,st); 302 pt r=tp-root; 303 pt vec=e*r; 304 pt ans=r*cos(A)+vec*sin(A)+root; 305 return pp(ans.x,ans.y); 306 } 307 int main(){ 308 while (scanf("%d",&lou.n)&&lou.n) { 309 for (int i=0; i<lou.n; ++i) 310 scanf("%lf%lf%lf",&lou.P[i].x,&lou.P[i].y,&lou.P[i].z); 311 lou.construct(); 312 double ansh=0,ansa=inf; 313 if(lou.n<=2) 314 { 315 printf("0.000 0.000\n"); 316 } 317 else if(lou.n==3) 318 { 319 ansh=0; 320 ansa=(lou.P[1]-lou.P[0])^(lou.P[2]-lou.P[0]); 321 ansa/=2.0; 322 printf("%.3lf %.3lf\n",ansh,ansa); 323 324 } 325 else { 326 for (int i=0; i<lou.cnt; ++i) { 327 pt p1=(lou.P[lou.F[i].b]-lou.P[lou.F[i].a])*(lou.P[lou.F[i].c]-lou.P[lou.F[i].a]); 328 pt e=pt(0,0,1); 329 pt vec=p1*e; 330 double A=p1^e/p1.len(); 331 A=acos(A); 332 if(fabs(A-pi)>EPS&&fabs(A)>EPS){ 333 pt s=pt(0,0,0); 334 for (int k=0; k<lou.n; ++k) ps[k]=rotate(s,vec,lou.P[k],A); 335 } 336 else 337 { 338 for(int k=0; k<lou.n; ++k) ps[k].x=lou.P[k].x,ps[k].y=lou.P[k].y; 339 } 340 double h=0; 341 for (int j=0; j<lou.n; ++j) 342 h=max(lou.ptoface(lou.P[j],i),h); 343 if (h<ansh) 344 continue; 345 Graham(); 346 double a=0; 347 for (int k=1; k<top-1; ++k){ 348 a+=fabs(Cross(ps[res[0]],ps[res[k]],ps[res[k+1]])); 349 } 350 a/=2.0; 351 if (fabs(h-ansh)<EPS) { 352 ansa=min(ansa,a); 353 } 354 else 355 ansa=a; 356 ansh=h; 357 } 358 printf("%.3lf %.3lf\n",ansh,ansa); 359 } 360 } 361 }
Problem I
签到题,就是计算所有数的平方和
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cstring> 7 #include<string> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #include<queue> 12 using namespace std; 13 typedef long long ll; 14 ll n; 15 int main() 16 { 17 while (~scanf("%lld",&n)) 18 { 19 if (n==0) break; 20 ll sum=0; 21 while (n--) 22 { 23 ll x; 24 scanf("%lld",&x); 25 sum+=x*x; 26 } 27 printf("%lld\n",sum); 28 } 29 return 0; 30 }
Problem J
由于只有裤子跟衣服或鞋子搭配不合法
因此可以求出每条裤子跟多少衣服和鞋子搭配是合法的
然后用乘法原理进行统计即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cstring> 7 #include<string> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #include<queue> 12 using namespace std; 13 typedef long long ll; 14 int n,m,k,sum1[1010],sum2[1010]; 15 char s1[11],s2[11]; 16 int main() 17 { 18 while (~scanf("%d%d%d",&n,&m,&k)) 19 { 20 if (n==0&&m==0&&k==0) break; 21 int q; 22 int i; 23 for (i=1;i<=m;i++) 24 { 25 sum1[i]=n; 26 sum2[i]=k; 27 } 28 scanf("%d",&q); 29 while (q--) 30 { 31 int x,y; 32 scanf("%s%d%s%d",s1,&x,s2,&y); 33 if (s1[0]=='c') sum1[y]--; 34 else sum2[x]--; 35 } 36 ll ans=0; 37 for (i=1;i<=m;i++) 38 ans+=1ll*sum1[i]*sum2[i]; 39 printf("%lld\n",ans); 40 } 41 return 0; 42 }
Problem K
根据题意进行模拟即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cstring> 7 #include<string> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #include<queue> 12 using namespace std; 13 #define y1 dfggf 14 #define y2 kkljk 15 const int d[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; 16 int c1,s1,t1,c2,s2,t2,n,t; 17 int main() 18 { 19 while (~scanf("%d",&n)) 20 { 21 if (n==0) break; 22 char c[2]; 23 scanf("%s%d%d",c,&s1,&t1); 24 if (c[0]=='E') c1=0; 25 else if (c[0]=='S') c1=1; 26 else if (c[0]=='W') c1=2; 27 else c1=3; 28 scanf("%s%d%d",c,&s2,&t2); 29 if (c[0]=='E') c2=0; 30 else if (c[0]=='S') c2=1; 31 else if (c[0]=='W') c2=2; 32 else c2=3; 33 scanf("%d",&t); 34 int i; 35 int x1=1,y1=1,x2=n,y2=n; 36 for (i=1;i<=t;i++) 37 { 38 int nx1=x1+d[c1][0]*s1; 39 int ny1=y1+d[c1][1]*s1; 40 if (nx1<1) 41 { 42 nx1=1+(1-nx1); 43 c1=1; 44 } 45 if (nx1>n) 46 { 47 nx1=n-(nx1-n); 48 c1=3; 49 } 50 if (ny1<1) 51 { 52 ny1=1+(1-ny1); 53 c1=0; 54 } 55 if (ny1>n) 56 { 57 ny1=n-(ny1-n); 58 c1=2; 59 } 60 int nx2=x2+d[c2][0]*s2; 61 int ny2=y2+d[c2][1]*s2; 62 if (nx2<1) 63 { 64 nx2=1+(1-nx2); 65 c2=1; 66 } 67 if (nx2>n) 68 { 69 nx2=n-(nx2-n); 70 c2=3; 71 } 72 if (ny2<1) 73 { 74 ny2=1+(1-ny2); 75 c2=0; 76 } 77 if (ny2>n) 78 { 79 ny2=n-(ny2-n); 80 c2=2; 81 } 82 if (nx1==nx2&&ny1==ny2) 83 swap(c1,c2); 84 else 85 { 86 if (i%t1==0) 87 { 88 c1--; 89 if (c1==-1) c1=3; 90 } 91 if (i%t2==0) 92 { 93 //cout<<c2<<" "; 94 c2--; 95 //cout<<i<<" "<<c2<<endl; 96 if (c2==-1) c2=3; 97 } 98 } 99 x1=nx1; 100 y1=ny1; 101 x2=nx2; 102 y2=ny2; 103 //cout<<i<<endl; 104 //cout<<x1<<" "<<y1<<" "<<c1<<endl; 105 //cout<<x2<<" "<<y2<<" "<<c2<<endl; 106 } 107 printf("%d %d\n",x1,y1); 108 printf("%d %d\n",x2,y2); 109 } 110 return 0; 111 }