SOJ 1071. Floors

题目大意:一块由t(1<=t<=100)块瓦片组成的地板,允许我们对地板进行切割,每一刀必须沿着瓦片的边缘且保证每个瓦片必须完整将地板一分为二,直到不能对地板进行切割,求不能再切割的地板的最大面积。
解题思路:分治递归。如果地板能够切割,则将地板一分为二再分别切割。判断地板能不能被切割:对每个瓦片的左上角顶点和右下角顶点所在的横纵坐标进行判断,判断水平和竖直方向上是否有其他瓦片会被切开,若无且该切法能使得原地板一分为二,则可以进行切割。若地板不能被切割,则计算面积,比较获取最大面积。

代码如下:

  1 #include <cstdio>
  2 #include <vector>
  3 using namespace std;
  4 
  5 struct Point {
  6     int x, y;
  7     //Point(const Point &other) : x(other.x) , y(other.y) {}
  8     bool operator<(const Point &other) const {
  9         return x < other.x || (x == other.x && y < other.y);
 10     }
 11     bool operator==(const Point &other) const {
 12         return x == other.x && y == other.y;
 13     }
 14     bool operator!=(const Point &other) const {
 15         return !(*this == other);
 16     }
 17 };
 18 struct Tile {
 19     Point leftTop, rightBottom;
 20     //Tile(const Point &lt, const Point &rb) : leftTop(lt), rightBottom(rb) {}
 21 };
 22 
 23 bool canHorizonalCut(const Point &point, const vector<Tile> &tiles) {
 24     for (int i = 0; i < tiles.size(); ++i) {
 25         const Point &leftTop = tiles[i].leftTop;
 26         const Point &rightBottom = tiles[i].rightBottom;
 27         if (leftTop.x < point.x && point.x < rightBottom.x) return false;
 28     }
 29     return true;
 30 }
 31 
 32 bool canVerticalCut(const Point &point, const vector<Tile> &tiles) {
 33     for (int i = 0; i < tiles.size(); ++i) {
 34         const Point &leftTop = tiles[i].leftTop;
 35         const Point &rightBottom = tiles[i].rightBottom;
 36         if (leftTop.y < point.y && point.y < rightBottom.y) return false;
 37     }
 38     return true;
 39 }
 40 
 41 void cutFloor(const vector<Tile> &tiles, int &area_max) {
 42     Point mostLeftTop = tiles[0].leftTop, mostRightBottom = tiles[0].rightBottom;
 43     for (int i = 1; i < tiles.size(); ++i) {
 44         mostLeftTop = tiles[i].leftTop < mostLeftTop ? tiles[i].leftTop : mostLeftTop;
 45         mostRightBottom = mostRightBottom < tiles[i].rightBottom ? tiles[i].rightBottom : mostRightBottom;
 46     }
 47     for (int i = 0; i < tiles.size(); ++i) {
 48         Point point = tiles[i].leftTop;
 49         if (point.x != mostLeftTop.x && point.x != mostRightBottom.x && canHorizonalCut(point, tiles)) {
 50             vector<Tile> upHalf, downHalf;
 51             for (int i = 0; i < tiles.size(); ++i) {
 52                 const Point &rightBottom = tiles[i].rightBottom;
 53                 if (rightBottom.x <= point.x) upHalf.push_back(tiles[i]);
 54                 else downHalf.push_back(tiles[i]);
 55             }
 56             if (upHalf.empty() || downHalf.empty()) {
 57                 while (true);
 58             }
 59             cutFloor(upHalf, area_max);
 60             cutFloor(downHalf, area_max);
 61             return;
 62         } else if (point.y != mostLeftTop.y && point.y != mostRightBottom.y && canVerticalCut(point, tiles)) {
 63             vector<Tile> leftHalf, rightHalf;
 64             for (int i = 0; i < tiles.size(); ++i) {
 65                 const Point &rightBottom = tiles[i].rightBottom;
 66                 if (rightBottom.y <= point.y) leftHalf.push_back(tiles[i]);
 67                 else rightHalf.push_back(tiles[i]);;
 68             }
 69             if (leftHalf.empty() || rightHalf.empty()) {
 70                 while (true);
 71             }
 72             cutFloor(leftHalf, area_max);
 73             cutFloor(rightHalf, area_max);
 74             return;
 75         }
 76         point = tiles[i].rightBottom;
 77         if (point.x != mostLeftTop.x && point.x != mostRightBottom.x && canHorizonalCut(point, tiles)) {
 78             vector<Tile> upHalf, downHalf;
 79             for (int i = 0; i < tiles.size(); ++i) {
 80                 const Point &rightBottom = tiles[i].rightBottom;
 81                 if (rightBottom.x <= point.x) upHalf.push_back(tiles[i]);
 82                 else downHalf.push_back(tiles[i]);
 83             }
 84             if (upHalf.empty() || downHalf.empty()) {
 85                 while (true);
 86             }
 87             cutFloor(upHalf, area_max);
 88             cutFloor(downHalf, area_max);
 89             return;
 90         } else if (point.y != mostLeftTop.y && point.y != mostRightBottom.y && canVerticalCut(point, tiles)) {
 91             vector<Tile> leftHalf, rightHalf;
 92             for (int i = 0; i < tiles.size(); ++i) {
 93                 const Point &rightBottom = tiles[i].rightBottom;
 94                 if (rightBottom.y <= point.y) leftHalf.push_back(tiles[i]);
 95                 else rightHalf.push_back(tiles[i]);;
 96             }
 97             if (leftHalf.empty() || rightHalf.empty()) {
 98                 while (true);
 99             }
100             cutFloor(leftHalf, area_max);
101             cutFloor(rightHalf, area_max);
102             return;
103         }
104     }
105 
106     int area = (mostRightBottom.y - mostLeftTop.y) * (mostRightBottom.x - mostLeftTop.x);
107     area_max = area_max > area ? area_max : area;
108 }
109 
110 int main() {
111     int t;
112     scanf("%d", &t);
113     while (t--) {
114         int x_max, y_max;
115         scanf("%d%d", &x_max, &y_max);
116         int n;
117         scanf("%d", &n);
118         vector<Tile> tiles(n);
119         for (int i = 0; i < n; ++i) {
120             scanf("%d%d%d%d", &tiles[i].leftTop.x, &tiles[i].leftTop.y, &tiles[i].rightBottom.x, &tiles[i].rightBottom.y);
121         }
122         int area_max = 0;
123         cutFloor(tiles, area_max);
124         printf("%d
", area_max);
125     }
126     return 0;
127 }
原文地址:https://www.cnblogs.com/mchcylh/p/4972753.html