【USACO 5.3.2】Window Area

Window Area
IV Balkan Olympiad

You've just be assigned the project of implemented a windowing interface. This windowing interface is fairly simple, and fortunately, you don't have to display the actual windows. There are 5 basic operations:

  1. Create a window
  2. Bring a window to the top
  3. Put a window to the bottom
  4. Destroy a window
  5. Output what percentage of a window is visible (i.e., isn't covered by windows above it).

In the input, the operations appear in the following format:

  • Create window: w(I,x,y,X,Y)
  • Bring window to top: t(I)
  • Put window on bottom: b(I)
  • Destroy window: d(I)
  • Output percentage visible: s(I)

The I is a unique identifier for each window, which is one character. The character can be any of 'a'..'z', 'A'..'Z', and '0'..'9'. No extra spaces will appear in the input.

(x,y) and (X,Y) are opposite corners of the window. When a window is created, it is put `on top'. You can't create a window with an identifier that is already in use, but you can destroy a window and then create a new one with the identifier of the destroyed window. Coordinates will be positive integers, and all windows will be of non-zero area (x != X and y != Y). The x and y coordinates are between 1 and 32767 inclusive.

PROGRAM NAME: window

INPUT FORMAT

The input file consists of a sequence of commands to your interpreter. They will be listed one per line. Terminate the program when no more input is available

SAMPLE INPUT (file window.in)

w(a,10,132,20,12)
w(b,8,76,124,15)
s(a)

OUTPUT FORMAT

Output lines only for the s() commands. Of course, there might be several s() commands (but no more than 500) so the output should be a sequence of percentages, one per line, stating the percentage of the windows that are visible. The percentages should be rounded to 3 decimal places.

SAMPLE OUTPUT (file window.out)

49.167


矩形分割么。
我们开一个链表队列,支持插入和删除,动态开点。每一个节点存储矩形的信息。它们的顺序代表它们的覆盖的先后。
然后就简单了。
我们可以想象一下:一个矩形向上飘,遇到另一个矩形,然后相撞了,这个矩形分裂成了几个矩形继续向上飘。
这不就是递归了么。。。
然后统计最后没有撞到其他矩形的部分的总和就可以了。
代码有点长,表示很难驾驭指针。
/*
TASK:window
LANG:C++
*/
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

struct Node
{
    char dat;
    double x0, y0, x1, y1;
    Node *next;
}*head, *tail, *p;

void ins_back(Node *&now)
{
    if (head == NULL) head = tail = now;
    else
    {
        tail->next = now;
        tail = now;
    }
}

void ins_front(Node *&now)
{
    now->next = head;
    head = now;
}

Node *find(char x)
{
    for (Node *it = head; it != NULL; it = it->next)
        if (it->dat == x) return it;
    return NULL;
}

double cbs(Node *&now, double x0, double y0, double x1, double y1)
{
    if (x0 >= x1 || y0 >= y1) return 0;
    if (now == NULL) return (x1 - x0) * (y1 - y0);
    return cbs(now->next, x0, y0, min(x1, now->x0), y1)
            + cbs(now->next, max(x0, now->x0), y0, min(x1, now->x1), min(y1, now->y0))
            + cbs(now->next, max(x0, now->x0), max(y0, now->y1), min(x1, now->x1), y1)
            + cbs(now->next, max(x0, now->x1), y0, x1, y1);
}

int main()
{
    freopen("window.in", "r", stdin);
    freopen("window.out", "w", stdout);
    char cmd[100];
    while (scanf("%s", cmd) == 1)
    {
        if (cmd[0] == 'w')
        {
            p = new Node;
            sscanf(cmd, "%*c%*c%c,%lf,%lf,%lf,%lf", &p->dat, &p->x0, &p->y0, &p->x1, &p->y1);
            if (p->x0 > p->x1) swap(p->x0, p->x1);
            if (p->y0 > p->y1) swap(p->y0, p->y1);
            p->next = NULL;
            ins_back(p);
        }
        else
        {
            char x;
            sscanf(cmd, "%*c%*c%c", &x);
            
            if (cmd[0] == 't')
            {
                if (head == NULL || head == tail) continue;
                if (head->dat == x)
                {
                    p = head;
                    head = head->next;
                    p->next = NULL;
                    ins_back(p);
                }
                else
                    for (Node *it = head; it->next != tail; it = it->next)
                        if (it->next->dat == x)
                        {
                            p = it->next;
                            it->next = p->next;
                            p->next = NULL;
                            ins_back(p);
                            break;
                        }
            }
            
            if (cmd[0] == 'b')
            {
                if (head == NULL) continue;
                for (Node *it = head; it->next != NULL; it = it->next)
                    if (it->next->dat == x)
                    {
                        if (it->next == tail)
                        {
                            p = tail;
                            it->next = NULL;
                            tail = it;
                            ins_front(p);
                        }
                        else
                        {
                            p = it->next;
                            it->next = p->next;
                            p->next = NULL;
                            ins_front(p);
                        }
                        break;
                    }
            }
            
            if (cmd[0] == 'd')
            {
                if (head == NULL) continue;
                if (head->dat == x)
                {
                    p = head;
                    head = head->next;
                    p->next = NULL;
                    delete p;
                }
                else
                    for (Node *it = head; it->next != NULL; it = it->next)
                        if (it->next->dat == x)
                        {
                            if (it->next == tail)
                            {
                                p = tail;
                                tail = it;
                                tail->next = NULL;
                            }
                            else
                            {
                                p = it->next;
                                it->next = p->next;
                            }
                            p->next = NULL;
                            delete p;
                            break;
                        }
            }
            
            if (cmd[0] == 's')
            {
                p = find(x);
                if (p == NULL) printf("0.000\n");
                else printf("%.3lf\n", 100.0 * cbs(p->next, p->x0, p->y0, p->x1, p->y1) / (p->x1 - p->x0) / (p->y1 - p->y0));
            }
        }
    }
    return 0;
}

 

posted @ 2016-01-17 15:55  albertxwz  阅读(435)  评论(0编辑  收藏  举报