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\n", area_max);
125     }
126     return 0;
127 }
时间: 2024-08-06 21:23:10

SOJ 1071. Floors的相关文章

Laravel 5.4 migrate报错:Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `us ers_email_unique`(`email`))

Laravel 5.4 migrate报错:Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `us     ers_email_unique`(`email`)) public function up() { Schema::create('users', function (Blu

Using innodb_large_prefix to avoid ERROR 1071

Using innodb_large_prefix to avoid ERROR 1071 单列索引限制上面有提到单列索引限制767,起因是256×3-1.这个3是字符最大占用空间(utf8).但是在5.5以后,开始支持4个字节的uutf8.255×4>767, 于是增加了一个参数叫做 innodb_large_prefix.这个参数默认值是OFF.当改为ON时,允许列索引最大达到3072.       联合索引3072我们知道InnoDB一个page的默认大小是16k.由于是Btree组织,要

SOJ 4445 2015四川省赛模拟题

背景:赛场上就是因为没开这道题,而没拿到银,回来A了,感觉代码能力还是很弱,一定要先想好再敲,而且注重代码的函数化,这样无论是观感,还是调试都要好很多,逻辑要清晰,看代码要仔细,提交之前通读代码. 题意:起点在原点的frog,开始向右运动,且碰到障碍物就右转,问转多少次? 思路:关键是图的大小范围是109,无法存下,只有用类似链表的方法来存图.这里用了两个容器,一个以X为基准,一个一Y为基准,这两个容器设置很特殊,是为了满足题中特殊的查询需要:查询前进方向最近障碍物. 我的代码: #includ

UVA 718 - Skyscraper Floors(数论)

UVA 718 - Skyscraper Floors 题目链接 题意:在一个f层高的楼上,有e个电梯,每个电梯有x,y表示y + k * x层都可以到,现在要问从a层能否到达b层(中间怎么换乘电梯不限制) 思路:对于两个电梯间能不能换乘,只要满足y[i] + xx x[i] == y[j] + yy y[j].然后移项一下,就可以用拓展欧几里得求解,进而求出x,y的通解,然后利用通解范围x' >= 0, y' >= 0, x[i] x' + y[i] <= f, x[j] y' + y

soj 1015 Jill&#39;s Tour Paths 解题报告

题目描述: 1015. Jill's Tour Paths Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description Every year, Jill takes a bicycle tour between two villages. There are different routes she can take between these villages, but she does have an upper limit

SOJ 1051 Biker&#39;s Trip Odometer

题目大意:多组测试样例,每组测试样例输入3个数,第一个表示车轮的直径(浮点型,单位英寸),第二个表示车轮的转数(整型),第三个表示花费的时间(浮点型,单位秒). 求解车轮的总路程(单位:英里)和平均速度(单位:英里/每小时). 以"Trip #: distance MPH"的格式输出. 当转数输入为零时,结束程序. 解题思路:本题主要考察单位的转化,具体的转化系数在题目中有给出.求车轮周长的π是3.1415927. 先将直径的英寸单位转化为英里单位,将时间的秒单位转化为小时. 代码如下

Lightoj 1071 - Baker Vai (双线程DP)

题目连接: http://lightoj.com/volume_showproblem.php?problem=1071 题目大意: 一个n*m的格子,Baker Vai要从(1,1)到(n,m)再回到(1,1),每到一个格子可以收集格子上的数字(每个格子只能走一次,(1,1)这个格子除外),问最终搜集的数字之和最大为多少? 解题思路: 可以把题目转化为求两个对象同时从(1,1)出发到(n,m)途中不能相遇,状态转移的时候可以用dp[step][x][y],step代表当前步数,x,y分别代表两

uva 718 - Skyscraper Floors(数论+bfs)

题目链接:uva 718 - Skyscraper Floors 题目大意:一栋大楼,有F层楼,E个电梯,现在要从A层到B层,问是否可行,每个电梯给出Xi和Yi,代表这个电梯可以到达的层数Yi+k?Xi(k≥0) 解题思路:建图,以A,B以及电梯为节点建图,将可以到达A,B这两层的电梯与这两点建边,在将两两电梯可以达到同一层的建边,判断方法为:Yi+aXi=Yj+bXj,移项得:aXi+bXj=Yj?Yi,即是一个线性方程,用拓展欧几里得算法求出通解的形式,判断是否存在通解在0~F之间即可. #

soj 1034 Forest_求树的深度和宽度

题目链接 题意:给你n个节点,m条边,每条边是有向的,这颗树不能有自环,问这颗树的深度和宽度 思路: 不合法情况 1,入度大于1,即存在两条指向同一顶点的边 2,一条入点和出点都相同的边 3,一条变得入点和出点深度已知,但不符合出点的深度是入点的深度加1 4,点入深度未知但出点深度已知 5,遍历完以后,有顶点未遍历,说明有多个根 树的宽度是指,同一层最多有多少个节点 #include <iostream> #include<cstdio> #include<cstring&g