POJ 2318 TOYS

来源:互联网 发布:龙与地下城 知乎 编辑:程序博客网 时间:2024/06/08 14:42

题目大意:

        有一个矩形盒子里面有n块斜的挡板(1 ≤ n ≤ 5,000),矩形盒子左上角坐标为(x1, y1),右下角坐标为(x2, y2),接着会给出每个挡板的信息(Ui, Li),表示挡板的上端点为(Ui, y1),下端点为(Li, y2),其中保证各个挡板不相交,并且挡板信息按照从左往右的顺序依次给出,接下来给出m个点的坐标(1 ≤ m ≤ 5,000)(xi, yi),输入保证点不会落在挡板上,但是可能后落在矩形边框上,但绝不会落在矩形外。

        现有多个测例,每个测例都会给出上述信息,输入以n = 0结束,对于每个测例,要求从左到右输出每个隔间中点的个数,形式为"i: n",表示第i个隔间中有n个点,每个隔间占一行,隔间编号从0 ~ n共n + 1个,每个测例之间的输出用空格隔开。

题目链接

注释代码:

/*                                         * Problem ID : POJ 2318 TOYS * Author     : Lirx.t.Una                                         * Language   : C++                             * Run Time   : 235 ms                                         * Run Memory : 292 KB                                        */#include <iostream>#include <cstring>#include <cstdio>//挡板的最大数量#defineMAXN5000using namespace std;//矩形的左上角坐标以及右下角坐标intx1, x2;inty1, y2;structPoint {//表示点//可以用来记录挡板信息//也可以用来记录普通点的信息//如果是挡板信息则x, y表示Ui和Liintx, y;Point(void) {}Point(int xx, int yy) : x(xx), y(yy) {}friend istream &operator>>(istream &is, Point &p) {is >> p.x >> p.y;return is;}intoperator*(Point &p2) {//计算叉积//左操作数为点,右操作数为挡板//设点为p0,挡板上端点为p1,下端点为p2Pointpp1(p2.y - x, y2 - y);//得到向量p0->p2Pointpp2(p2.x - p2.y, y1 - y2);//得到向量p2->p1return pp1.x * pp2.y - pp1.y * pp2.x;//计算向量pp1×pp2//如果>0表示点在挡板左边否则就在挡板右边(因为后面的二分保证了叉积不是大于0就是小于0//不可能等于0)}};Pointp[MAXN + 2];//n + 2块挡板,矩形左边和右边也算两个,但是不用记录因为二分查找用不到intcnt[MAXN + 1];//记录每个隔间中点的个数intn, m;//挡板数和点数intbsrch(Point &_p) {//二分查找_p点落在哪个隔间中intlft, rht, mid;lft = 0;rht = n + 1;while ( lft + 1 < rht ) {//规定左右最小间距为1,这样就永远都不会查到矩形左右两边了//也就避免了检验叉积为0的特殊情况了mid = ( lft + rht ) >> 1;if  ( _p * p[mid] > 0 ) rht = mid;//在mid左边else lft = mid;//右边}return lft;//隔间号和左挡板一致}intmain() {inti;Point_p;//点while ( scanf("%d", &n), n ) {memset(cnt, 0, sizeof(cnt));scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);for ( i = 1; i <= n; i++ ) cin >> p[i];while ( m-- ) {cin >> _p;cnt[ bsrch(_p) ]++;}for ( i = 0; i <= n; i++ )printf("%d: %d\n", i, cnt[i]);putchar('\n');}return 0;}
无注释代码:

#include <iostream>#include <cstring>#include <cstdio>#defineMAXN5000using namespace std;intx1, x2;inty1, y2;structPoint {intx, y;Point(void) {}Point(int xx, int yy) : x(xx), y(yy) {}friend istream &operator>>(istream &is, Point &p) {is >> p.x >> p.y;return is;}intoperator*(Point &p2) {Pointpp1(p2.y - x, y2 - y);Pointpp2(p2.x - p2.y, y1 - y2);return pp1.x * pp2.y - pp1.y * pp2.x;}};Pointp[MAXN + 2];intcnt[MAXN + 1];intn, m;intbsrch(Point &_p) {intlft, rht, mid;lft = 0;rht = n + 1;while ( lft + 1 < rht ) {mid = ( lft + rht ) >> 1;if  ( _p * p[mid] > 0 ) rht = mid;else lft = mid;}return lft;}intmain() {inti;Point_p;while ( scanf("%d", &n), n ) {memset(cnt, 0, sizeof(cnt));scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);for ( i = 1; i <= n; i++ ) cin >> p[i];while ( m-- ) {cin >> _p;cnt[ bsrch(_p) ]++;}for ( i = 0; i <= n; i++ )printf("%d: %d\n", i, cnt[i]);putchar('\n');}return 0;}

0 0
原创粉丝点击