您的位置:首页 > 其它

《算法竞赛-训练指南》第一章-1.23_LA 3695

2013-07-24 17:21 295 查看
想死的心都有了,一只都不在状态啊今天!浪费时间浪费清楚,可耻!

不知道怎么的,内心好烦躁,一直静心不下来呀!算了,晚上好好刷题吧,昨天的一场比赛,自己什么都没做出来,看了解题报告觉得写的飘忽飘忽的真没意思,不如《算法竞赛》这本书上讲的好。所以,不会的题目我也懒得去学习了,还是学习这上面的知识点吧,但是真的有点慢,学的太慢,所以不行,还得加快速度。

描述一下这个题目,就是给出平面上n个点,找出一个矩形,使得边界上包含尽量多的点。

这个就可以引申,到矩形内有多少个点,等等矩形的问题。

解决方法呢,就是扫描,先把所有的信息存到结点内,然后按照y排序,当然你也可以按照x排序,扫描y。但是根据大体人的习惯,还是习惯扫描x的。所以就把y排序了,然后去重,求得,一共有多少个不重复的边,然后暴力所有的任意两条边,然后扫描次两条边的x。

这时候确定边上的点,就需要用到几个数组,比如说on,on2,还有left数组,left数组表明的是此线左边的线上的点,on代表的此线上的,并且不在两条y上面的点,而on2,表示此线上的点,并且包含在y上面的点,

那么left的递推公式就很容易得出了left[i] = left[i - 1] + on2[i] - on[i];

而总共的也就好表示了ans = left[j] + on2[j] - left[i] + on[i];

贴出代码,烦躁,学校的网老是不稳定!

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>

using namespace std;

const int MAXN = 100 + 11;

struct Point
{
int x, y;
bool operator < (const Point &t) const
{
return x < t.x;
}
}p[MAXN];

int on[MAXN];

int on2[MAXN];

int left[MAXN];

int y[MAXN];

int N;

int solve()
{
sort(p, p + N);
sort(y, y + N);
int m = unique(y, y + N) - y;
if (m <= 2)
{
return N;
}
int ans = 0;
for (int a = 0; a < m; a++)
{
for (int b = a + 1; b < m; b++)
{
int ymin = y[a];
int ymax = y[b];
int k = 0;
for (int i = 0; i < N; i++)
{
if (i == 0 || p[i].x != p[i - 1].x)
{
k++;
on[k] = 0;
on2[k] = 0;
left[k] = left[k - 1] + on2[k - 1] - on[k - 1];
}
if (p[i].y > ymin && p[i].y < ymax)
{
on[k]++;
}
if (p[i].y >= ymin && p[i].y <= ymax)
{
on2[k]++;
}
}
if (k <= 2)
{
return N;
}
int M = 0;
for (int j = 1; j <= k; j++)
{
ans = max(ans, left[j] + on2[j] + M);
M = max(M, on[j] - left[j]);
}
}
}
return ans;
}

int main()
{
int cas = 1;
int a, b;
while (scanf("%d", &N) != EOF)
{
if (N == 0)
{
break;
}
for (int i = 0; i < N; i++)
{
scanf("%d%d", &a, &b);
p[i].x = a;
p[i].y = b;
y[i] = b;
}
int ans = solve();
printf("Case %d: %d\n", cas++, ans);
}
// system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: