HDU 5301 Buildings(思考)


タイトルリンク:http://acm.hdu.edu.cn/showproblem.php?pid=5301
問題:
Buildings
Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1421    Accepted Submission(s): 400
Problem Description
Your current task is to make a ground plan for a residential building located in HZXJHS. So you must determine a way to split the floor building with walls to make apartments in the shape of a rectangle. Each built wall must be paralled to the building's sides.
The floor is represented in the ground plan as a large rectangle with dimensions
n×m , where each apartment is a smaller rectangle with dimensions
a×b located inside. For each apartment, its dimensions can be different from each other. The number
a and
b must be integers.
Additionally, the apartments must completely cover the floor without one
1×1 square located on
(x,y) . The apartments must not intersect, but they can touch.
For this example, this is a sample of
n=2,m=3,x=2,y=2 .
HDU 5301 Buildings(思维)_第1张图片
To prevent darkness indoors, the apartments must have windows. Therefore, each apartment must share its at least one side with the edge of the rectangle representing the floor so it is possible to place a window.
Your boss XXY wants to minimize the maximum areas of all apartments, now it's your turn to tell him the answer.
 
Input
There are at most
10000 testcases.
For each testcase, only four space-separated integers,
n,m,x,y(1≤n,m≤108,n×m>1,1≤x≤n,1≤y≤m) .
 
Output
For each testcase, print only one interger, representing the answer.
 
Sample Input

   
   
   
   
2 3 2 2 3 3 1 1

 
Sample Output

   
   
   
   
1 2
Hint
Case 1 : HDU 5301 Buildings(  )_ 2   You can split the floor into five 1×1 apartments. The answer is 1. Case 2: HDU 5301 Buildings(  )_ 3   You can split the floor into three 2×1 apartments and two 1×1 apartments. The answer is 2. HDU 5301 Buildings(  )_ 4   If you want to split the floor into eight 1×1 apartments, it will be unacceptable because the apartment located on (2,2) can't have windows.

 
Source
2015 Multi-University Training Contest 2
 
問題を解く:
    四角い格子は間違いなく1*kなので、このようにしてやっと面積を最小にすることができて、最初、時限を見て、二分の答えだと思っています.しかし,悪い点がなければ,答えはans=(min(n,m)+1)/2であることが分かった.しかし、悪い点があり、2つの特殊な状況が発生します.
1.nはmに等しく、nは奇数であり、同時に悪い点が中心点の位置にある場合、答えはans-1である.
2.(n>mと仮定する)悪点がある位置で形成された4つの枠に面した距離のうち、総長m−1の2つのうちの1つがansより大きく、その辺が位置し、上または下でカバーできない場合は、その点(そのカバーできない辺の上で悪点に最も近い点)から3つの方向に最も近い距離を答えとする.
3.残りの場合、答えはansで変わりません.
まとめ:
    実は、試合の時、以上の2つの特殊な情況は、すべてすでに探し当てて、しかし、構想はあまりにも乱れて、理性的に問題を分析することができません.このような問題は,筋道立てて分析し,討論すべきである.考えてから手書きに行きます.
コード:
#include <iostream>
#include <cmath>
using namespace std;
int max(int a,int b)
{
    return a>b?a:b;
}
int min(int a,int b)
{
    return a<b?a:b;
}
int main()
{
    int n,m,x,y,ans;
    while(cin>>n>>m>>x>>y)
    {
      ans=(min(n,m)+1)/2;
      if(n==m)
      {
        if(n%2)
        {
            if(x==(n+1)/2&&y==(m+1)/2)
                ans--;
        }
      }
      else
      {
          int le,ri,up,dw;
          if(n<m)
          {
             swap(n,m);
             swap(x,y);
          }
          le=y;
          ri=m-y+1;
          up=x;
          dw=n-x+1;
          if(m%2)
          {
              if(abs(le-ans)>1)
              {
                  if(up>ans&&dw>ans)
                  {
                      ans=max(le-1,ri-1);
                      ans=min(ans,up);
                      ans=min(ans,dw);
                  }
              }
          }
          else
          {
              if(!(le==ans||le==ans+1))
              {
                  if(up>ans&&dw>ans)
                  {
                      ans=max(le-1,ri-1);
                      ans=min(ans,up);
                      ans=min(ans,dw);
                  }
              }
          }
      }
      cout<<ans<<endl;
    }
    return 0;
}