USACO 2016 February Contest, Bronze Problem 3. Load Balancing

FJ的N头牛都站在FJ的二维农场上的一些明显的坐标(x1,y1)...(xn,yn)上(1<=N<=100,并且xi和yi都是正奇数,大小不会超过B)。FJ想以建造一条很长(实际上是无限长)的南北向的栅栏的方式来分割他的农场,这个栅栏表示的直线符合直线方程(或者说一次函数)x=a(a是一个偶数,请确保FJ不会将栅栏穿过任何一头牛)。FJ同时还想建造另一条很长(实际上也是无限长)的东西向的栅栏,这个栅栏表示的直线同样满足直线方程y=b,其中b是一个偶数。这两条栅栏相交于点(a,b),并且这两条栅栏一起将他的农场分成四块。

FJ想选择a和b使得出现在这四块区域里的牛的个数是“平衡的”,即没有一块区域里有太多的牛。如果使得M是四块区域里牛的数量的最大值,那么FJ想让M最小。请帮助他决定M的最小值。

前五个数据,B不超过100。在所有的数据里,B不超过1,000,000。

输入格式 (balancing.in):
第一行的输入是一个整数N,下面N行每行包含一只牛的位置,即其的x和y坐标。

输出格式 (balancing.out):
只有一行,即最小的M。

样例输入:
7
7 3
5 5
7 13
3 1
11 7
5 3
9 1
样例输出:
2
================================================================
在平面直角坐标系上有 n 个点,第 i 个点的横坐标记作 xi,纵坐标记作 yi,保证 xi 和 yi 都是 奇数且 1<=xi,yi<=10^6.要求在横轴和纵轴上分别找直线 x=a 和 y=b 将所有点分为四 部分.保证 a,b 均为偶数,这样一来两直线上不会有任何点,可以直接分.
记两直线的交点为(a,b)则有四部分:
Xi<=a 且 yi<=b,直观理解为(a,b)的”左上角”.
Xi<=a 且 yi>b,直观理解为(a,b)的”右上角”.
Xi>a 且 yi<=b,直观理解为(a,b)的”左下角”.
Xi>a 且 yi>b,直观理解为(a,b)的”右下角”.
求四部分中包含最多点的部分最小的情况是多少.
考虑到数据范围较小,1<=n<=100,可以枚举 a,b 并验证,时间复杂度为 O(n^3),不超时.
代码如下:
 
    

#include
#include
const int MAXN = 105;
int n;
int x[MAXN],y[MAXN];
int main() {
freopen("balancing.in","r",stdin);
freopen("balancing.out","w",stdout);
int b;
scanf("%d%d",&n,&b);
for(int i = 0;i < n;i++) {
scanf("%d%d",&x[i],&y[i]);
}
int ans = n;
for(int i = 0;i < n;i++) {
for(int j = 0;j < n;j++) {
int ne = 0,nw = 0,se = 0,sw = 0;
for(int k = 0;k < n;k++) {
nw += (x[k] <= x[i] && y[k] <= y[j]);
ne += (x[k] <= x[i] && y[k] > y[j]);
sw += (x[k] > x[i] && y[k] <= y[j]);
se += (x[k] > x[i] && y[k] > y[j]);
}
ans = std :: min(ans , std :: max( std :: max(nw,ne) , std ::max(sw,se) ));
}
}
printf("%d\n",ans);
return 0;
}

你可能感兴趣的:(解题报告,DFS,USACO)