这两题基本一样:
poj 2398
可以暴力 16ms , 二分 0ms
题意:一个箱子被多个隔板分割不同的小空间,隔板不会相交, 问每个隔板有多少个玩具
输出: 2: 5 有两个玩具的空间有5个, 并且玩具的个数是按升序输出。
思路:
利用叉乘判断点在线段的左侧还是右侧,主要是用二分进行计算,
以隔板和箱子的两侧为二分基础,(即有 n+2 个线段 从0到n+1,)
判断点在哪一个小空间中,注意二分中的小细节。
二分:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1200;
struct node//记录板和箱子两侧的坐标
{
int sx, sy, ex, ey;
} dp[maxn];
struct temp//记录玩具的坐标
{
int x, y;
} to[maxn];
int n, m, x0, y0, x1, y1;
int a[maxn];
bool cmp(node a, node b)
{
return a.sx < b.sx;
}
bool text(temp a, node b)
{
int c = (a.x-b.ex)*(b.sy-b.ey)-(b.sx-b.ex)*(a.y-b.ey);
if(c < 0) return true;
return false;
}
void input()
{
dp[0].sx = x0, dp[0].sy = y0, dp[0].ex = x0, dp[0].ey = y1;//箱子两侧的坐标
dp[n+1].sx = x1, dp[n+1].sy = y0, dp[n+1].ex = x1, dp[n+1].ey = y1;
for(int i = 1; i <= n; i++)//板的坐标
{
int u, v;
scanf("%d %d", &u, &v);
dp[i].sx = u, dp[i].sy = y0, dp[i].ex = v, dp[i].ey = y1;
}
sort(dp, dp+n+2, cmp);//要对其进行排序
memset(a, 0, sizeof(a));//初始化为0
for(int i = 0; i < m; i++)//输入玩具的坐标 并二分判断在哪一个小空间中
{
scanf("%d%d", &to[i].x, &to[i].y);
int l = 0, r = n+1;
while(l < r)
{
int mid = (l+r)>>1;
if(text(to[i], dp[mid])) r = mid;//不要再减一, 在这个地方错了好几次,
else l = mid+1;
}
a[r]++;
}
}
void output()
{
printf("Box\n");
for(int i = 1; i <= m; i++)
{
int sum = 0;
for(int j = 1; j <= n+1; j++)
if(a[j] == i) sum++;
if(sum) printf("%d: %d\n", i, sum);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
while(scanf("%d%d%d%d%d%d", &n, &m, &x0, &y0, &x1, &y1) != EOF && n)
{
input();
output();
}
return 0;
}
暴力:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1020;
struct node
{
int sx, sy, ex, ey;
} dp[maxn];
struct temp
{
int x, y;
} to[maxn];
int n, m, x0, y0, x2, y2;
int a[maxn];
bool cmp(node a, node b)
{
return a.sx < b.sx;
}
int Ijs(temp a, node b)
{
return (a.x-b.ex)*(b.sy-b.ey)-(b.sx-b.ex)*(a.y-b.ey);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
while(scanf("%d%d%d%d%d%d", &n, &m, &x0, &y0, &x2, &y2) != EOF && n)
{
int u, v;
for(int i = 0; i < n; i++)
{
scanf("%d%d", &u, &v);
dp[i].sx = u, dp[i].sy = y0, dp[i].ex = v, dp[i].ey = y2;
}
sort(dp, dp+n, cmp);
memset(a, 0, sizeof(a));
for(int i = 0; i < m; i++)
{
int flag = 0;
scanf("%d%d", &to[i].x, &to[i].y);
for(int j = 0; j < n; j++)
{
if(j == 0 && Ijs(to[i], dp[j]) < 0) a[j+1]++, flag = 1;
else if(j != 0 && Ijs(to[i], dp[j]) < 0 && Ijs(to[i], dp[j-1]) > 0) a[j+1]++, flag = 1;
}
if(!flag) a[n+1]++;
}
printf("Box\n");
for(int i = 1; i <= m; i++)
{
int sum = 0;
for(int j = 1; j <= n+1; j++)
if(a[j] == i) sum++;
if(sum) printf("%d: %d\n", i, sum);
}
}
}
poj 2318
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 6000;
struct node
{
int sx, sy, ex, ey;
} dp[maxn];
struct temp
{
int x, y;
} to[maxn];
int n, m, x0, y0, x1, y1;
int a[maxn];
bool Ijs(temp a, node b)
{
int c = (a.x-b.ex)*(b.sy-b.ey)-(b.sx-b.ex)*(a.y-b.ey);
if(c < 0) return true;
return false;
}
inline void input()
{
dp[0].sx = x0, dp[0].sy = y0, dp[0].ex = x0, dp[0].ey = y1;
dp[n+1].sx = x1, dp[n+1].sy = y0, dp[n+1].ex = x1, dp[n+1].ey = y1;
for(int i = 1; i <= n; i++)
{
cin >> dp[i].sx >> dp[i].ex;
dp[i].sy = y0, dp[i].ey = y1;
}
memset(a, 0, sizeof(a));
for(int i = 0; i < m; i++)
{
cin >> to[i].x >> to[i].y;
int l = 0, r = n+1;
while(l < r)
{
int mid = (l+r)>>1;
if(Ijs(to[i], dp[mid])) r = mid;
else l = mid+1;
}
a[r-1]++;
}
}
inline void output()
{
for(int i = 0; i <= n; i++)
cout << i <<":" << " " << a[i] << endl;
cout << endl;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
while(cin >> n >> m >> x0 >> y0 >> x1 >> y1 && n)
{
input();
output();
}
}