<Codeforces Beta Round #38> D. Vasya the Architect
这是一个数学题。判断一个brick能否保持平衡的方法是看它的重心在xoy平面上的投影是否落在它下方的那一个brick上(包括边界)。故此这题涉及计算重心坐标的问题,对于单个brick,计算重心坐标是一个显而易见的问题,假设对角顶点在xoy上的投影的坐标分别是(x1,y1),(x2,y2),则重心在xoy上的投影的坐标就是两者的中点((x1 + x2)/2,(y1 + y2)/2)。那么,多个brick组成的复合体的重心怎么求?运用以下公式:
Pw = (P[1] * W[1] + P[2]*W[2] + ... + P[n] * W[n]) / (W[1] + W[2] + ... + W[n])
比如要求y,则Pw是复合体的重心的纵坐标,p[i]是复合体中brick[i]的重心纵坐标,w[i]是brick[i]的重量。
AC Code:
//Memory: 1400 KB Time: 30 MS //Language: GNU C++ 4.6 Result: Accepted #include <iostream> #include <cstdio> #include <cmath> using namespace std; struct BRICK { int x1, x2, y1, y2; //对角坐标 double wei; //重量 double cenx, ceny; //重心坐标 }b[101]; int main() { int n, x1, x2, y1, y2; int i, j, k; double w, cx, cy; //分别是总的重量,重心横坐标、纵坐标 scanf("%d", &n); for(i = 1; i <= n; i++) { scanf("%d %d %d %d", &b[i].x1, &b[i].y1, &b[i].x2, &b[i].y2); b[i].wei = pow(((b[i].x1 - b[i].x2)*(b[i].x1 - b[i].x2) + (b[i].y1 - b[i].y2)*(b[i].y1 - b[i].y2))/2.0, 1.5); b[i].cenx = 0.5*(b[i].x1 + b[i].x2); b[i].ceny = 0.5*(b[i].y1 + b[i].y2); } for(i = 2; i <= n; i++) { cx = b[i].cenx, cy = b[i].ceny, w = b[i].wei; //往下搜看加上b[i]后会不会使得下面的brick不稳 for(j = i - 1; j > 0; j--) { if((cx - b[j].x1)*(cx - b[j].x2) > 0 || (cy - b[j].y1)*(cy - b[j].y2) > 0) { break; } //计算新的重心和重量 cx = (w*cx + b[j].wei*b[j].cenx)/(w + b[j].wei); cy = (w*cy + b[j].wei*b[j].ceny)/(w + b[j].wei); w += b[j].wei; } if(j) break; } printf("%d\n", i - 1); return 0; }