//template <class T>
class Node
{
template <typename U>
friend class List;
Node<Rect>* _prev;
Node<Rect>* _next;
Rect _val;
public:
Node(const Rect& val, Node* prev, Node* next) : _val(val) , _prev(prev) , _next(next) {}
const Rect& val() { return _val; }
Node<Rect>* prev() { return _prev; }
Node<Rect>* next() { return _next; }
};
//template <class T>
class Node
{
//template <typename U>
friend class List;
Node Rect* _prev;
Node Rect* _next;
Rect _val;
public:
Node(const Rect& val, Node* prev, Node* next) : _val(val) , _prev(prev) , _next(next) {}
const Rect& val() { return _val; }
Node Rect* prev() { return _prev; }
Node Rect* next() { return _next; }
};
//template <class Rect>
class Node
{
template <typename U>
friend class List;
Node* _prev;
Node* _next;
Rect _val;
public:
Node(const Rect& val, Node* prev, Node* next) : _val(val) , _prev(prev) , _next(next) {}
const Rect& val() { return _val; }
Node* prev() { return _prev; }
Node* next() { return _next; }
};
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <conio.h>
typedef unsigned long Int;
class Point
{
public:
Int x;
Int y;
Point(Int _x, Int _y) : x(_x), y(_y) {}
};
class Rect
{
public:
Point lt; // left top
Point rb; // right bottom
Rect(const Point & _lt, const Point & _rb) : lt(_lt), rb(_rb) {}
};
//template <class Rect>
class Node
{
// template <typename U>
friend class List;
Node* _prev;
Node* _next;
Rect _val;
public:
Node(const Rect& val, Node* prev, Node* next) : _val(val) , _prev(prev) , _next(next) {}
const Rect& val() { return _val; }
Node* prev() { return _prev; }
Node* next() { return _next; }
};
//template <class T>
class List
{
protected:
Node<Rect>* _first;
Node<Rect>* _last;
public:
List() : _first(0), _last(0) {}
~List()
{
Node* curr = begin();
while (curr != end())
{
Node* next = curr->next();
delete curr;
curr = next;
}
}
void push_back(const Rect& x)
{
// если список пуст
if (0 == _first)
{
_first = new Node<Rect>(x, 0, 0);
_last = _first;
}
// если нет -- добавляем в конец
else
{
Node* newNode = new Node(x, _last, 0);
_last->_next = newNode;
_last = newNode;
}
}
void erase(Node* node)
{
Node* curr = node;
if (curr != _first) curr->prev()->_next = curr->next();
if (curr != _last) curr->next()->_prev = curr->prev();
// если узел и начало и конец -- это единственный элемент списка
if (curr == _first && curr == _last) { _first = _last = 0; }
delete curr;
}
void insertFront(List& list)
{
// если список пуст, просто замещаем
if (0 == _first)
{
_first = list._first;
_last = list._last;
}
else
{
list._last->_next = _first;
_first->_prev = list._last;
_first = list._first;
}
list._first = list._last = 0;
}
Node* begin() { return _first; }
Node* end() { return 0; }
size_t size()
{
size_t s = 0;
for (Node* curr = begin(); curr != end(); curr = curr->next())
++s;
return s;
}
};
bool inbetween(Int x, Int a, Int b)
{
return a <= x && x <= b;
}
bool pointInRect(const Point & p, const Rect & r)
{
return inbetween(p.x, r.lt.x, r.rb.x)
&& inbetween(p.y, r.lt.y, r.rb.y);
}
// точка должны лежать внутри прямоугольника
List<Rect> breakRect(const Rect & r, const Point & p)
{
List<Rect> rs;
// если есть место слева
if (p.x > r.lt.x) rs.push_back(Rect(r.lt, Point(p.x-1, r.rb.y)));
// справа
if (p.x < r.rb.x) rs.push_back(Rect(Point(p.x+1, r.lt.y), r.rb));
// если есть место сверху
if (p.y > r.lt.y) rs.push_back(Rect(r.lt, Point(r.rb.x, p.y-1)));
// снизу
if (p.y < r.rb.y) rs.push_back(Rect(Point(r.lt.x, p.y+1), r.rb));
return rs;
}
// лежит ли первый прямоугольник во втором
bool into(const Rect & r, const Rect & big)
{
return pointInRect(r.lt, big)
&& pointInRect(r.rb, big);
}
using namespace std;
int main()
{
Int N, M, K;
fscanf(stdin, "%lu%lu%lu", &N, &M, &K);
// список прямоугольников
List<Rect> rs;
// вначале есть прямоугольник во всё поле
rs.push_back(Rect(Point(1,1), Point(N,M)));
//printRects(rs);
for (Int i = 0; i < K; ++i)
{
// препятствие
Int x, y;
fscanf(stdin, "%lu%lu", &x, &y);
Point p(x, y);
// смотрим, не надо ли разбить что-то из имеющихся прямоугольников
Node<Rect>* it = rs.begin();
while (it != rs.end())
{
Rect r = it->val(); // текущий прямоугольник
// если точка внутри прямоугольника -- надо бить
if (pointInRect(p, r))
{
List<Rect> broken = breakRect(r, p);
//rs.splice(it, broken);
rs.insertFront(broken);
Node<Rect>* next = it->next();
rs.erase(it);
it = next;
}
else
{
it = it->next();
}
}
//printRects(rs);
}
// чистим список прямоугольников от прямоугольничков, содержащихся в больших
Node<Rect>* itBig = rs.begin();
while (itBig != rs.end())
{
Rect big = itBig->val(); // прямоугольник, в который будем пытаться вмещать остальные
Node<Rect>* it = rs.begin();
while (it != rs.end())
{
// сам с собой проверять нечего
if (it == itBig)
{
it = it->next();
continue;
}
Rect r = it->val(); // прямоугольник, который постараемся выкинуть, как слишком маленький
if (into(r, big))
{
Node<Rect>* next = it->next();
rs.erase(it);
it = next;
}
else
{
it = it->next();
}
}
itBig = itBig->next();
}
fprintf(stdout, "%lu", rs.size());
cin.get();
getch();
return 0;
}
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <conio.h>
typedef unsigned long Int;
class Point
{
public:
Int x;
Int y;
Point(Int _x, Int _y) : x(_x), y(_y) {}
};
class Rect
{
public:
Point lt; // left top
Point rb; // right bottom
Rect(const Point & _lt, const Point & _rb) : lt(_lt), rb(_rb) {}
};
//template <class Rect>
class Node
{
// template <typename U>
friend class List;
Node* _prev;
Node* _next;
Rect _val;
public:
Node(const Rect& val, Node* prev, Node* next) : _val(val) , _prev(prev) , _next(next) {}
const Rect& val() { return _val; }
Node* prev() { return _prev; }
Node* next() { return _next; }
};
//template <class T>
class List
{
protected:
Node* _first;
Node* _last;
public:
List() : _first(0), _last(0) {}
~List()
{
Node* curr = begin();
while (curr != end())
{
Node* next = curr->next();
delete curr;
curr = next;
}
}
void push_back(const Rect& x)
{
// åñëè ñïèñîê ïóñò
if (0 == _first)
{
_first = new Node(x, 0, 0);
_last = _first;
}
// åñëè íåò -- äîáàâëÿåì â êîíåö
else
{
Node* newNode = new Node(x, _last, 0);
_last->_next = newNode;
_last = newNode;
}
}
void erase(Node* node)
{
Node* curr = node;
if (curr != _first) curr->prev()->_next = curr->next();
if (curr != _last) curr->next()->_prev = curr->prev();
// åñëè óçåë è íà÷àëî è êîíåö -- ýòî åäèíñòâåííûé ýëåìåíò ñïèñêà
if (curr == _first && curr == _last) { _first = _last = 0; }
delete curr;
}
void insertFront(List& list)
{
// åñëè ñïèñîê ïóñò, ïðîñòî çàìåùàåì
if (0 == _first)
{
_first = list._first;
_last = list._last;
}
else
{
list._last->_next = _first;
_first->_prev = list._last;
_first = list._first;
}
list._first = list._last = 0;
}
Node* begin() { return _first; }
Node* end() { return 0; }
size_t size()
{
size_t s = 0;
for (Node* curr = begin(); curr != end(); curr = curr->next())
++s;
return s;
}
};
bool inbetween(Int x, Int a, Int b)
{
return a <= x && x <= b;
}
bool pointInRect(const Point & p, const Rect & r)
{
return inbetween(p.x, r.lt.x, r.rb.x)
&& inbetween(p.y, r.lt.y, r.rb.y);
}
// òî÷êà äîëæíû ëåæàòü âíóòðè ïðÿìîóãîëüíèêà
List breakRect(const Rect & r, const Point & p)
{
List rs;
// åñëè åñòü ìåñòî ñëåâà
if (p.x > r.lt.x) rs.push_back(Rect(r.lt, Point(p.x-1, r.rb.y)));
// ñïðàâà
if (p.x < r.rb.x) rs.push_back(Rect(Point(p.x+1, r.lt.y), r.rb));
// åñëè åñòü ìåñòî ñâåðõó
if (p.y > r.lt.y) rs.push_back(Rect(r.lt, Point(r.rb.x, p.y-1)));
// ñíèçó
if (p.y < r.rb.y) rs.push_back(Rect(Point(r.lt.x, p.y+1), r.rb));
return rs;
}
// ëåæèò ëè ïåðâûé ïðÿìîóãîëüíèê âî âòîðîì
bool into(const Rect & r, const Rect & big)
{
return pointInRect(r.lt, big)
&& pointInRect(r.rb, big);
}
using namespace std;
int main()
{
Int N, M, K;
fscanf(stdin, "%lu%lu%lu", &N, &M, &K);
// ñïèñîê ïðÿìîóãîëüíèêîâ
List rs;
// âíà÷àëå åñòü ïðÿìîóãîëüíèê âî âñ¸ ïîëå
rs.push_back(Rect(Point(1,1), Point(N,M)));
//printRects(rs);
for (Int i = 0; i < K; ++i)
{
// ïðåïÿòñòâèå
Int x, y;
fscanf(stdin, "%lu%lu", &x, &y);
Point p(x, y);
// ñìîòðèì, íå íàäî ëè ðàçáèòü ÷òî-òî èç èìåþùèõñÿ ïðÿìîóãîëüíèêîâ
Node* it = rs.begin();
while (it != rs.end())
{
Rect r = it->val(); // òåêóùèé ïðÿìîóãîëüíèê
// åñëè òî÷êà âíóòðè ïðÿìîóãîëüíèêà -- íàäî áèòü
if (pointInRect(p, r))
{
List broken = breakRect(r, p);
//rs.splice(it, broken);
rs.insertFront(broken);
Node* next = it->next();
rs.erase(it);
it = next;
}
else
{
it = it->next();
}
}
//printRects(rs);
}
// ÷èñòèì ñïèñîê ïðÿìîóãîëüíèêîâ îò ïðÿìîóãîëüíè÷êîâ, ñîäåðæàùèõñÿ â áîëüøèõ
Node* itBig = rs.begin();
while (itBig != rs.end())
{
Rect big = itBig->val(); // ïðÿìîóãîëüíèê, â êîòîðûé áóäåì ïûòàòüñÿ âìåùàòü îñòàëüíûå
Node* it = rs.begin();
while (it != rs.end())
{
// ñàì ñ ñîáîé ïðîâåðÿòü íå÷åãî
if (it == itBig)
{
it = it->next();
continue;
}
Rect r = it->val(); // ïðÿìîóãîëüíèê, êîòîðûé ïîñòàðàåìñÿ âûêèíóòü, êàê ñëèøêîì ìàëåíüêèé
if (into(r, big))
{
Node* next = it->next();
rs.erase(it);
it = next;
}
else
{
it = it->next();
}
}
itBig = itBig->next();
}
fprintf(stdout, "%lu", rs.size());
cin.get();
getch();
return 0;
}
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.