POJ 2318 几何初步 + 二分 及其 姊妹题 POJ 2398
来源:互联网 发布:其他设备 网络控制器 编辑:程序博客网 时间:2024/06/11 21:52
叉积+二分
如果toys在当前板的左边 cross(L,toys,U) < 0
反之在右边会 > 0
根据这个,我们进行二分;
为什么最后得到的不是mid而是l呢?
我们来看这张图.
加入现在是 l = 2 , r = 5;mid = 3; toy在4纸板右边,5纸板左边,
执行l = l +1 = 3, r = 5, mid = 4;依然>0 执行,
l = l + 1 = 4,r = 5, mid = 4; 依然大于0 ,执行
l = l + 1 = 5, r= 5, 退出; 此时l = 5, 之前toy确实在l右边,可是现在在它左边了.(有的情况还是会在右边)
所以我们后面要加一个判断:
if(cross(CardB[r].L, Toys, CardB[r].U) < 0) N_Toys[l]++;else N_Toys[l+1]++;
显然,我们同样可以:
if(cross(CardB[r].L, Toys, CardB[r].U) > 0) N_Toys[r+1]++;else N_Toys[r]++;
那么,如果利用mid 改怎么改写代码呢?
for(int i = 0; i < m; i++) { l = 0, r = n-1; scanf("%d%d",&Toys.x,&Toys.y); while(l <= r) { mid = (l + r) >> 1; if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0) l = mid + 1; else r = mid - 1; } if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0) N_Toys[mid+1]++; else N_Toys[mid]++; }
/* *POJ 2318 *fuqiang *几何初步 *2013/8/2*/#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <algorithm>using namespace std;const int maxn = 5000+3;const double PI = 4.0*atan(1.0);const double eps = 1e-8;struct point{ int x; int y;} Toys;struct Line{ point U; point L;} CardB[maxn];int N_Toys[maxn];int cross(const point &p0, const point &p1, const point &p2) //计算叉积{ return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);}int main(){#ifndef ONLINE_JUDGE freopen("in","r",stdin);#endif int n,m,x1,y1,x2,y2; while(scanf("%d",&n) && n) { scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2); for(int i = 0; i < n; i++) { scanf("%d%d", &CardB[i].U.x, &CardB[i].L.x); CardB[i].U.y = y1; CardB[i].L.y = y2; } memset(N_Toys,0,sizeof(N_Toys)); int l, r, mid, ans, p; for(int i = 0; i < m; i++) { l = 0, r = n-1; scanf("%d%d",&Toys.x,&Toys.y); while(l < r) { mid = (l + r) >> 1; if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0) l = mid + 1; else r = mid; } if(cross(CardB[r].L, Toys, CardB[r].U) < 0) N_Toys[l]++; else N_Toys[l+1]++; } for(int i = 0; i <= n; i++) { printf("%d: %d\n",i,N_Toys[i]); } printf("\n"); }}
还有个更好的点子,别人的代码:
将最后一个点也作为纸板,此时 我们只需要返回l:
while (l <= r){ mid = (l + r) >> 1; if ( cal (low[mid], high[mid], cc) > 0 ) l = mid + 1; else r = mid - 1; } return l;}
POJ 2398
加个排序,统计后输出,注意t>0
/* *POJ 2318 *fuqiang *几何初步 *2013/8/2*/#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <algorithm>using namespace std;const int maxn = 5000+3;const double PI = 4.0*atan(1.0);const double eps = 1e-8;struct point{ int x; int y;} Toys;struct Line{ point U; point L;} CardB[maxn];int N_Toys[maxn];int cross(const point &p0, const point &p1, const point &p2) //计算叉积{ return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);}int cmp(Line a, Line b)//sort...{ return a.L.x < b.L.x;}int main(){#ifndef ONLINE_JUDGE freopen("in","r",stdin);#endif int n,m,x1,y1,x2,y2; while(scanf("%d",&n) && n) { scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2); for(int i = 0; i < n; i++) { scanf("%d%d", &CardB[i].U.x, &CardB[i].L.x); CardB[i].U.y = y1; CardB[i].L.y = y2; } sort(CardB,CardB+n,cmp); //sort memset(N_Toys,0,sizeof(N_Toys)); int l, r, mid, ans, p; for(int i = 0; i < m; i++) { l = 0, r = n-1; scanf("%d%d",&Toys.x,&Toys.y); while(l <= r) { mid = (l + r) >> 1; if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0) l = mid + 1; else r = mid - 1; } if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0) N_Toys[mid+1]++; else N_Toys[mid]++; } sort(N_Toys,N_Toys+n+1); printf("Box\n"); int st = 0; while(N_Toys[st] == 0) st++; for(int i = st; i <= n; ) { int num = 1; printf("%d: ",N_Toys[i]); for(int j = i++; j <= n; j++,i++) { if(N_Toys[i]==N_Toys[j]) num++; else break; } printf("%d\n",num); }// printf("\n"); }}
- POJ 2318 几何初步 + 二分 及其 姊妹题 POJ 2398
- POJ 2318 几何二分
- poj 2398-几何二分搜索
- poj 2318-几何二分搜索
- POJ 2318 计算几何+二分
- POJ 2318 几何 POJ 2398
- POJ 2318 TOYS 计算几何 入门题 叉积 + 二分
- POJ 2398 计算几何+二分+排序
- poj 2398 Toy Storage 计算几何+二分
- poj 2318 toys 计算几何+二分
- POJ 1905 Expanding Rods几何题,二分
- POJ 1905(几何+二分)
- POJ 1267 Fence(几何 + 二分)
- 【计算几何】POJ 2318 & POJ 2398
- POJ 2318 2398 计算几何
- POJ 2318 TOYS (计算几何,向量积,二分查找)
- POJ 2318 TOYS(计算几何)(二分)
- POJ 2318 TOYS [叉积判断+二分查找]【计算几何】
- uva748 ( 高精度 浮点数幂)
- FLASH轮播广告 在谷歌浏览器中不显示的解决办法(FLash轮播放广告在谷歌浏览器中无法显示处理方法)
- JAVA学习十二:接口(interface)
- JAVA学习十三:多态性
- JAVA学习十四:内部类
- POJ 2318 几何初步 + 二分 及其 姊妹题 POJ 2398
- css 箭头
- JAVA学习十五:异常
- JAVA学习十六:包(package)
- 暑期训练-泰山挑夫1
- rails-sidekiq
- JAVA学习十七:多线程
- HDU 4604 Deque 二分最长上升子序列
- php 正则匹配中文