【Usaco2015 JAN】Cow Rectangles

来源:互联网 发布:悦木之源泥娃娃知乎 编辑:程序博客网 时间:2024/05/17 03:11

很丑

另一份代码

还没有。。。。

#include<cstdio>#include<algorithm>using namespace std;const int maxm = 500 + 10;const int maxn = 1000 + 10;const int INF = 0xfffffff;int pre[maxn][maxn], n, l, r, d, u;char ch;struct answer{    int point, area;}ans;struct G{    int x, y;}Gsx[maxm];int cnt, nowpoint;void Readin(){    scanf("%d", &n);    int x, y;    l = d = INF;    u = r = -INF;    for(int i = 1; i <= n; i ++){        scanf("%d %d %c", &x, &y, &ch);        x ++;        y ++;        if(ch == 'H')            pre[y][x] ++;        else            Gsx[++ cnt] = (G){x, y};        l = min(l, x);        r = max(r, x);        d = min(d, y);        u = max(u, y);    }}bool Cmpx(G a, G b){    return a.x == b.x ? a.y < b.y : a.x < b.x;}void Init(){    for(int i = d; i <= u; i ++)        for(int j = l; j <= r; j ++)            pre[i][j] += (pre[i][j - 1] + pre[i - 1][j] - pre[i - 1][j - 1]);    sort(Gsx + 1, Gsx + cnt + 1, Cmpx);    Gsx[cnt + 1] = (G){r + 1, 0};}void Check(){    for(int i = u; i >= d; i --){        for(int j = l; j <= r; j ++)            printf("%d ", pre[i][j]);        printf("\n");    }    printf("\n");    for(int i = 1; i <= cnt; i ++)        printf("(%d, %d) ", Gsx[i].x, Gsx[i].y);}int Ef(int up, int down, int left, int right, int point){    int uu = up - 1, dd = down + 1;    while(uu > dd){        int mid = (uu + dd) / 2;        if(pre[mid][right - 1] - pre[down][right - 1] - pre[mid][left] + pre[down][left] < point)            dd = mid + 1;        else            if(pre[mid - 1][right - 1] - pre[down][right - 1] - pre[mid - 1][left] + pre[down][left] == point)                uu = mid - 1;            else{                uu = mid;                break;            }    }    up = uu;    dd = down + 1;    while(uu > dd){        int mid = (uu + dd) / 2;        if(pre[up][right - 1] - pre[mid - 1][right - 1] - pre[up][left] + pre[mid - 1][left] < point)            uu = mid - 1;        else            if(pre[up][right - 1] - pre[mid][right - 1] - pre[up][left] + pre[mid][left] == point)                dd = mid + 1;            else{                dd = mid;                break;            }    }    down = dd;    int ll = left + 1, rr = right - 1;    while(ll < rr){        int mid = (ll + rr) / 2;        if(pre[up][right - 1] - pre[down - 1][right - 1] - pre[up][mid - 1] + pre[down - 1][mid - 1] < point)            rr = mid - 1;        else            if(pre[up][right - 1] - pre[down - 1][right - 1] - pre[up][mid] + pre[down - 1][mid] == point)                ll = mid + 1;            else{                ll = mid;                break;            }    }    left = ll;    rr = right - 1;    while(ll < rr){        int mid = (ll + rr) / 2;        if(pre[up][mid] - pre[down - 1][mid] - pre[up][left - 1] + pre[down - 1][left - 1] < point)            ll = mid + 1;        else            if(pre[up][mid - 1] - pre[down - 1][mid - 1] - pre[up][left - 1] + pre[down - 1][left - 1] == point)                rr = mid - 1;            else{                rr = mid;                break;            }    }    right = rr;    return (right - left) * (up - down);}void Solve(){    int down, up;    ans.area = INF;    ans.point = -1;    for(int i = 1; i <= cnt; i ++){        down = d - 1;        up = u + 1;        for(int j = i + 1; j <= cnt + 1; j ++)            if(Gsx[j].y < up && Gsx[j].y > down || j == cnt + 1){                nowpoint = pre[up - 1][Gsx[j].x - 1] - pre[down][Gsx[j].x - 1] - pre[up - 1][Gsx[i].x] + pre[down][Gsx[i].x];                if(nowpoint < ans.point || nowpoint == 0){                    if(Gsx[j].y > Gsx[i].y)                        up = Gsx[j].y;                    else                        if(Gsx[j].y < Gsx[i].y)                            down = Gsx[j].y;                        else                            break;                    continue;                }                else{                    if(ans.point < nowpoint){                        ans.point = nowpoint;                        ans.area = Ef(up, down, Gsx[i].x, Gsx[j].x, nowpoint);                    }                    else                        ans.area = min(ans.area, Ef(up, down, Gsx[i].x, Gsx[j].x, nowpoint));                }                if(Gsx[j].y > Gsx[i].y)                    up = Gsx[j].y;                else                    if(Gsx[j].y < Gsx[i].y)                        down = Gsx[j].y;                    else                        break;            }    }    for(int i = d; i <= u; i ++){        down = d - 1;        up = u + 1;        for(int j = 1; j <= cnt + 1; j ++)            if(Gsx[j].y < up && Gsx[j].y > down || j == cnt + 1){                nowpoint = pre[up - 1][Gsx[j].x - 1] - pre[down][Gsx[j].x - 1] - pre[up - 1][l - 1] + pre[down][l - 1];                if(nowpoint < ans.point){                    if(Gsx[j].y > i)                        up = Gsx[j].y;                    else                        if(Gsx[j].y < i)                            down = Gsx[j].y;                        else                            break;                    continue;                }                else{                    if(ans.point < nowpoint){                        ans.point = nowpoint;                        ans.area = Ef(up, down, l - 1, Gsx[j].x, nowpoint);                    }                    else                        ans.area = min(ans.area, Ef(up, down, l - 1, Gsx[j].x, nowpoint));                }                if(Gsx[j].y > i)                    up = Gsx[j].y;                else                    if(Gsx[j].y < i)                        down = Gsx[j].y;                    else                        break;            }    }    printf("%d\n%d", ans.point, ans.area);}int main(){    freopen("cowrect.in", "r", stdin);    freopen("cowrect.out", "w", stdout);    Readin();    Init();//  Check();    Solve();    return 0;}

又写丑了好丑好丑真丑啊啊

又写丑了好丑好丑真丑啊啊

又写丑了好丑好丑真丑啊啊

又写丑了好丑好丑真丑啊啊

又写丑了好丑好丑真丑啊啊

又写丑了好丑好丑真丑啊啊

又写丑了好丑好丑真丑啊啊

又写丑了好丑好丑真丑啊啊

1 0
原创粉丝点击