1 条题解

  • 0
    @ 2025-5-19 20:11:47

    题目分析

    本题要求在矩形公园内找到最大的正方形板球场地,场地不能包含任何树木(树木可位于边界),且场地需与公园边界对齐。核心是枚举所有可能的正方形位置和边长,检查是否满足条件,并找到最大可行解。

    方法思路

    暴力枚举法(基础思路):

    枚举西南角坐标:遍历所有可能的正方形西南角坐标 (i,j)(i, j),其中 0iW0 \leq i \leq W0jH0 \leq j \leq H。枚举边长:对于每个坐标 (i,j)(i, j),从最大可能的边长(即 min(Wi,Hj)\min(W-i, H-j))开始递减尝试,直到找到不包含任何树木的正方形。检查树木冲突:对于每个候选正方形,检查所有树木是否在其内部(不含边界时需注意条件)。若不包含任何树木,则记录当前正方形的大小和位置。

    优化思路(减少枚举次数)提前终止:找到当前坐标下最大可行边长后,可直接跳过更小的边长尝试。利用树的坐标特性:若树木坐标已排序,可通过二分法快速判断是否存在冲突,但本题树木数量较少(N100N \leq 100),暴力检查已足够高效。

    #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
    上传者