1 条题解
-
0
题目分析
本题要求在矩形公园内找到最大的正方形板球场地,场地不能包含任何树木(树木可位于边界),且场地需与公园边界对齐。核心是枚举所有可能的正方形位置和边长,检查是否满足条件,并找到最大可行解。
方法思路
暴力枚举法(基础思路):
枚举西南角坐标:遍历所有可能的正方形西南角坐标 ,其中 ,。枚举边长:对于每个坐标 ,从最大可能的边长(即 )开始递减尝试,直到找到不包含任何树木的正方形。检查树木冲突:对于每个候选正方形,检查所有树木是否在其内部(不含边界时需注意条件)。若不包含任何树木,则记录当前正方形的大小和位置。
优化思路(减少枚举次数)提前终止:找到当前坐标下最大可行边长后,可直接跳过更小的边长尝试。利用树的坐标特性:若树木坐标已排序,可通过二分法快速判断是否存在冲突,但本题树木数量较少(),暴力检查已足够高效。
#include <cstdio> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <stack> #include <cctype> #include <utility> #include <map> #include <string> #include <climits> #include <set> #include <string> #include <sstream> #include <utility> #include <ctime> using std::priority_queue; using std::vector; using std::swap; using std::stack; using std::sort; using std::max; using std::min; using std::pair; using std::map; using std::string; using std::cin; using std::cout; using std::set; using std::queue; using std::string; using std::istringstream; using std::make_pair; using std::greater; const int INFI((INT_MAX-1) >> 1); int x[110], y[110]; int ax[110]; int ta[110]; int main() { int w, h, n; while(~scanf("%d%d%d", &n, &w, &h)) { int tn = 0; for(int i = 1; i <= n; ++i) { scanf("%d%d", x+i, y+i); ax[++tn] = x[i]; } ax[++tn] = 0; ax[++tn] = w; sort(ax+1, ax+1+tn); ax[0] = -1; int count = 0; for(int i = 1; i <= tn; ++i) if(ax[i] != ax[i-1]) ax[++count] = ax[i]; int ans = 0; int gx = 0, gy = 0; for(int i = 1; i <= count; ++i) for(int j = i+1; j <= count; ++j) { ta[1] = 0; ta[2] = h; int tc = 2; for(int k = 1; k <= tn; ++k) if(x[k] > ax[i] && x[k] < ax[j]) ta[++tc] = y[k]; sort(ta+1, ta+1+tc); int mx = 0; int ty1, ty2; for(int k = 2; k <= tc; ++k) { int temp = ta[k]-ta[k-1]; if(temp > mx) { mx = temp; ty1 = ta[k-1]; ty2 = ta[k]; } } int temp = min(ax[j]-ax[i], mx); if(temp > ans) { ans = temp; gx = ax[i]; gy = ty1; } } printf("%d %d %d\n", gx, gy, ans); } return 0; }
- 1
信息
- ID
- 1174
- 时间
- 1000ms
- 内存
- 64MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 1
- 上传者