//$EK 2013-03-05 added void IntegrationRule::DefineIntegrationRulePrism(IntegrationRule & integrationRule, int ruleOrder) { // we use a ready function, which provides a tetrahedral integration rule Vector x1, x2, xline, w, wline; GetIntegrationRuleTrig(x1, x2, w, ruleOrder); GetIntegrationRule(xline, wline, ruleOrder); for (int i = 1; i <= xline.Length(); ++i) xline(i) = (xline(i) + 1.)/2.; // and now we create a 3D integration rule integrationRule.integrationPoints.SetLen(x1.Length()*xline.Length()); assert(x1.Length() == x2.Length()); assert(x1.Length() == w.Length()); assert(xline.Length() == wline.Length()); int cnt = 1; for (int i1 = 1; i1 <= x1.GetLen(); i1++) { for (int i2 = 1; i2 <= xline.GetLen(); ++i2) { integrationRule.integrationPoints(cnt).x = x1(i1); integrationRule.integrationPoints(cnt).y = x2(i1); integrationRule.integrationPoints(cnt).z = xline(i2); //the /2. is due to the transformation of [-1,1] to [0,1] integrationRule.integrationPoints(cnt).weight = w(i1)*wline(i2)/2.; cnt++; } } }
void check(ll xt, ll yt) { int i; if(!(minx <= xline(xt,yt) && xline(xt,yt) <= maxx && miny <= yline(xt,yt) && yline(xt,yt) <= maxy)) return; ll curans = 0; for(i = 0; i < n; i++) curans += ABS(x[i] - xt) + ABS(y[i] - yt); if(curans < ans) ans = curans; }
int main() { int i, j; ll d, xm, ym; scanf("%d\n", &n); for(i = 0; i < n; i++) scanf("%lld %lld\n", &x[i], &y[i]); scanf("%lld\n", &d); minx = miny = -INF; maxx = maxy = INF; for(i = 0; i < n; i++) { minx = MAX(minx, xline(x[i] - d, y[i])); maxx = MIN(maxx, xline(x[i] + d, y[i])); miny = MAX(miny, yline(x[i], y[i] - d)); maxy = MIN(maxy, yline(x[i], y[i] + d)); } if(minx > maxx || miny > maxy) { printf("impossible\n"); return 0; } ans = INF; xm = median(x, n); ym = median(y, n); check(xm,ym); check(getx(minx,miny,true ),gety(minx,miny,true )); check(getx(minx,miny,true ),gety(minx,miny,false)); check(getx(minx,maxy,false),gety(minx,maxy,false)); check(getx(minx,maxy,true ),gety(minx,maxy,false)); check(getx(maxx,maxy,false),gety(maxx,maxy,true )); check(getx(maxx,maxy,false),gety(maxx,maxy,false)); check(getx(maxx,miny,true ),gety(maxx,miny,true )); check(getx(maxx,miny,false),gety(maxx,miny,true )); int border[4][3] = { {minx, 1, -minx}, {maxx, 1, -maxx}, {miny, -1, miny}, {maxy, -1, maxy} }; for(i = 0; i < 4; i++) { for(j = 0; j < n; j++) { pts[j*2] = x[j]; pts[j*2+1] = border[i][0] + border[i][1] * y[j]; } xm = median(pts, n * 2); ym = border[i][1] * xm + border[i][2]; check(xm,ym); } printf("%lld\n", ans); return 0; }
//$EK 2013-03-05 added void IntegrationRule::DefineIntegrationRulePyramid(IntegrationRule & integrationRule, int ruleOrder) { // we use a ready function, which provides a tetrahedral integration rule Vector x_z, xline, w_z, wline; //$EK I don't know why in z-direction one needs in increased order??? //------------------------------------------------------------------------- //FROM NGSolve ... prismatic integration rule (in intrule.cpp) // const IntegrationRule & quadrule = SelectIntegrationRule (ET_QUAD, order); // const IntegrationRule & segrule = SelectIntegrationRule (ET_SEGM, order+2); //const IntegrationPoint & ipquad = quadrule[i]; // .GetIP(i); //const IntegrationPoint & ipseg = segrule[j]; // .GetIP(j); //point[0] = (1-ipseg(0)) * ipquad(0); //point[1] = (1-ipseg(0)) * ipquad(1); //point[2] = ipseg(0); //weight = ipseg.Weight() * sqr (1-ipseg(0)) * ipquad.Weight(); //-------------------------------------------------------------------------- GetIntegrationRule(x_z, w_z, ruleOrder+2); GetIntegrationRule(xline, wline, ruleOrder); //adapt integration points to interval [0,1] instead of [-1,1] for (int i = 1; i <= xline.Length(); ++i) xline(i) = (xline(i) + 1.)/2.; for (int i = 1; i <= x_z.Length(); ++i) x_z(i) = (x_z(i) + 1.)/2.; // and now we create a 3D integration rule integrationRule.integrationPoints.SetLen(x_z.Length()*sqr(xline.Length())); assert(x_z.Length() == w_z.Length()); assert(xline.Length() == wline.Length()); int cnt = 1; for (int i = 1; i <= xline.GetLen(); i++) for (int j = 1; j <= xline.GetLen(); j++) for (int k = 1; k <= x_z.GetLen(); ++k) { double z = x_z(k); integrationRule.integrationPoints(cnt).x = xline(i)*(1-z); integrationRule.integrationPoints(cnt).y = xline(j)*(1-z); integrationRule.integrationPoints(cnt).z = z; //the /8. is due to the transformation of [-1,1] to [0,1] integrationRule.integrationPoints(cnt).weight = w_z(k) * sqr(1- z) * wline(i) * wline(j)/8.; cnt++; } }