2021-07-18 TOYS

TOYS

题目链接
题意:
有一个矩形盒子,放入n块按照x轴排序的不相交的隔板,这样就将矩形盒子分成了n+1块区域。现在将m个玩具放入这个矩形盒子,统计每个区域的玩具个数。

思路:
利用叉乘的性质判断在当前隔板的左边还是右边,由于每个玩具在隔板的左边或右边具有单调性,所以可以二分优化

ac代码:

枚举+二分O(mlogn)

#include <iostream>  
#include <stdio.h>  
#include <string.h>   
#include <stack>  
#include <queue>   
#include <map>  
#include <set>  
#include <vector>  
#include <math.h>  
#include <bitset>  
#include <algorithm>  
#include <climits>

using namespace std;
// `计算几何模板`
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;
//`Compares a double to zero`
int sgn(double x){
	if(fabs(x) < eps)return 0;
	if(x < 0)return -1;
	else return 1;
}
//square of a double
inline double sqr(double x){return x*x;}

struct Point{
	double x,y;
	Point(){}
	Point(double _x,double _y){
		x = _x;
		y = _y;
	}
	void input(){
		scanf("%lf%lf",&x,&y);
	}
	void output(){
		printf("%.2f %.2f\n",x,y);
	}
	bool operator == (Point b)const{
		return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;
	}
	bool operator < (Point b)const{
		return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;
	}
	Point operator -(const Point &b)const{
		return Point(x-b.x,y-b.y);
	}
	//叉积
	double operator ^(const Point &b)const{
		return x*b.y - y*b.x;
	}
	//点积
	double operator *(const Point &b)const{
		return x*b.x + y*b.y;
	}
	//返回长度
	double len(){
		return hypot(x,y);//库函数
	}
	//返回长度的平方
	double len2(){
		return x*x + y*y;
	}
	//返回两点的距离
	double distance(Point p){
		return hypot(x-p.x,y-p.y);
	}
	Point operator +(const Point &b)const{
		return Point(x+b.x,y+b.y);
	}
	Point operator *(const double &k)const{
		return Point(x*k,y*k);
	}
	Point operator /(const double &k)const{
		return Point(x/k,y/k);
	}
	//`计算pa  和  pb 的夹角`
	//`就是求这个点看a,b 所成的夹角`
	//`测试 LightOJ1203`
	double rad(Point a,Point b){
		Point p = *this;
		return fabs(atan2( fabs((a-p)^(b-p)),(a-p)*(b-p) ));
	}
	//`化为长度为r的向量`
	Point trunc(double r){
		double l = len();
		if(!sgn(l))return *this;
		r /= l;
		return Point(x*r,y*r);
	}
	//`逆时针旋转90度`
	Point rotleft(){
		return Point(-y,x);
	}
	//`顺时针旋转90度`
	Point rotright(){
		return Point(y,-x);
	}
	//`绕着p点逆时针旋转angle`
	Point rotate(Point p,double angle){
		Point v = (*this) - p;
		double c = cos(angle), s = sin(angle);
		return Point(p.x + v.x*c - v.y*s,p.y + v.x*s + v.y*c);
	}
};

const int N = 5010;
Point U[N], L[N];
int cnt[N];

bool check(Point a, Point b) {
    return sgn(a ^ b) == 1;
}

int main() {
    int n, m, x1, y1, x2, y2;
    while (scanf("%d", &n), n) {
        memset(cnt, 0, sizeof cnt);
        scanf("%d %d %d %d %d", &m, &x1, &y1, &x2, &y2);
        for (int i = 1; i <= n; ++ i) {
            int a, b;
            scanf("%d %d", &a, &b);
            U[i] = Point(a, y1), L[i] = Point(b, y2);
        }
        U[n + 1] = Point(x2, y1), L[n + 1] = Point(x2, y2);
        
        for (int i = 1; i <= m; ++ i) {
            int x, y;
            scanf("%d %d", &x, &y);
            
            int l = 1, r = n + 1, mid, ans;
            while (l <= r) {
                mid = l + r >> 1;
                if (check(U[mid] - L[mid], Point(x, y) - L[mid])) 
                    ans = mid, r = mid - 1;
                else l = mid + 1;
            }
            
            cnt[ans - 1] ++ ;
        }
        
        for (int i = 1; i <= n + 1; ++ i) {
        	printf("%d: %d\n", i - 1, cnt[i - 1]);
		}
		printf("\n");
    }
    return 0;
}

暴力枚举O(n*m)

#include <iostream>  
#include <stdio.h>  
#include <string.h>   
#include <stack>  
#include <queue>   
#include <map>  
#include <set>  
#include <vector>  
#include <math.h>  
#include <bitset>  
#include <algorithm>  
#include <climits>

using namespace std;
// `计算几何模板`
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;
//`Compares a double to zero`
int sgn(double x){
	if(fabs(x) < eps)return 0;
	if(x < 0)return -1;
	else return 1;
}
//square of a double
inline double sqr(double x){return x*x;}

struct Point{
	double x,y;
	Point(){}
	Point(double _x,double _y){
		x = _x;
		y = _y;
	}
	void input(){
		scanf("%lf%lf",&x,&y);
	}
	void output(){
		printf("%.2f %.2f\n",x,y);
	}
	bool operator == (Point b)const{
		return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;
	}
	bool operator < (Point b)const{
		return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;
	}
	Point operator -(const Point &b)const{
		return Point(x-b.x,y-b.y);
	}
	//叉积
	double operator ^(const Point &b)const{
		return x*b.y - y*b.x;
	}
	//点积
	double operator *(const Point &b)const{
		return x*b.x + y*b.y;
	}
	//返回长度
	double len(){
		return hypot(x,y);//库函数
	}
	//返回长度的平方
	double len2(){
		return x*x + y*y;
	}
	//返回两点的距离
	double distance(Point p){
		return hypot(x-p.x,y-p.y);
	}
	Point operator +(const Point &b)const{
		return Point(x+b.x,y+b.y);
	}
	Point operator *(const double &k)const{
		return Point(x*k,y*k);
	}
	Point operator /(const double &k)const{
		return Point(x/k,y/k);
	}
	//`计算pa  和  pb 的夹角`
	//`就是求这个点看a,b 所成的夹角`
	//`测试 LightOJ1203`
	double rad(Point a,Point b){
		Point p = *this;
		return fabs(atan2( fabs((a-p)^(b-p)),(a-p)*(b-p) ));
	}
	//`化为长度为r的向量`
	Point trunc(double r){
		double l = len();
		if(!sgn(l))return *this;
		r /= l;
		return Point(x*r,y*r);
	}
	//`逆时针旋转90度`
	Point rotleft(){
		return Point(-y,x);
	}
	//`顺时针旋转90度`
	Point rotright(){
		return Point(y,-x);
	}
	//`绕着p点逆时针旋转angle`
	Point rotate(Point p,double angle){
		Point v = (*this) - p;
		double c = cos(angle), s = sin(angle);
		return Point(p.x + v.x*c - v.y*s,p.y + v.x*s + v.y*c);
	}
};

const int N = 5010;
Point U[N], L[N];
int cnt[N];

int main() {
    int n, m, x1, y1, x2, y2;
    while (scanf("%d", &n), n) {
        memset(cnt, 0, sizeof cnt);
        scanf("%d %d %d %d %d", &m, &x1, &y1, &x2, &y2);
        for (int i = 1; i <= n; ++ i) {
            int a, b;
            scanf("%d %d", &a, &b);
            U[i] = Point(a, y1), L[i] = Point(b, y2);
        }
        
        for (int i = 1; i <= m; ++ i) {
            int x, y;
            scanf("%d %d", &x, &y);
            int j = 1;
            for (; j <= n; ++ j) {
                //U[j].output(), L[j].output();
                
                if (sgn((U[j] - L[j]) ^ (Point(x, y) - L[j])) == 1) {
					break;
				}
            }
            // cout << j << " ";
            // cout << endl;
            cnt[j - 1] ++ ;
        }
        
        for (int i = 1; i <= n + 1; ++ i) {
        	printf("%d: %d\n", i - 1, cnt[i - 1]);
		}
		printf("\n");
    }
    return 0;
}

Toy Storage

题意同上
区别这题直线未排序
排序+二分

#include <iostream>  
#include <stdio.h>  
#include <string.h>   
#include <stack>  
#include <queue>   
#include <map>  
#include <set>  
#include <vector>  
#include <math.h>  
#include <bitset>  
#include <algorithm>  
#include <climits>

using namespace std;
// `计算几何模板`
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;
//`Compares a double to zero`
int sgn(double x){
	if(fabs(x) < eps)return 0;
	if(x < 0)return -1;
	else return 1;
}
//square of a double
inline double sqr(double x){return x*x;}

struct Point{
	double x,y;
	Point(){}
	Point(double _x,double _y){
		x = _x;
		y = _y;
	}
	void input(){
		scanf("%lf%lf",&x,&y);
	}
	void output(){
		printf("%.2f %.2f\n",x,y);
	}
	bool operator == (Point b)const{
		return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;
	}
	bool operator < (Point b)const{
		return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;
	}
	Point operator -(const Point &b)const{
		return Point(x-b.x,y-b.y);
	}
	//叉积
	double operator ^(const Point &b)const{
		return x*b.y - y*b.x;
	}
	//点积
	double operator *(const Point &b)const{
		return x*b.x + y*b.y;
	}
	//返回长度
	double len(){
		return hypot(x,y);//库函数
	}
	//返回长度的平方
	double len2(){
		return x*x + y*y;
	}
	//返回两点的距离
	double distance(Point p){
		return hypot(x-p.x,y-p.y);
	}
	Point operator +(const Point &b)const{
		return Point(x+b.x,y+b.y);
	}
	Point operator *(const double &k)const{
		return Point(x*k,y*k);
	}
	Point operator /(const double &k)const{
		return Point(x/k,y/k);
	}
	//`计算pa  和  pb 的夹角`
	//`就是求这个点看a,b 所成的夹角`
	//`测试 LightOJ1203`
	double rad(Point a,Point b){
		Point p = *this;
		return fabs(atan2( fabs((a-p)^(b-p)),(a-p)*(b-p) ));
	}
	//`化为长度为r的向量`
	Point trunc(double r){
		double l = len();
		if(!sgn(l))return *this;
		r /= l;
		return Point(x*r,y*r);
	}
	//`逆时针旋转90度`
	Point rotleft(){
		return Point(-y,x);
	}
	//`顺时针旋转90度`
	Point rotright(){
		return Point(y,-x);
	}
	//`绕着p点逆时针旋转angle`
	Point rotate(Point p,double angle){
		Point v = (*this) - p;
		double c = cos(angle), s = sin(angle);
		return Point(p.x + v.x*c - v.y*s,p.y + v.x*s + v.y*c);
	}
};

struct Line{
    Point l, u;
//     Line(){}
// 	Line(Point _x,Point _y){
// 		l = _x;
// 		u = _y;
// 	}
    bool operator < (Line b) const{
        if (l == b.l) return u < b.u;
        return l < b.l;
    }
};

const int N = 5010;
Point U[N], L[N];
int cnt[N], qcnt[N];
Line LU[N];


bool check(Point a, Point b) {
    return sgn(a ^ b) == 1;
}

int main() {
    int n, m, x1, y1, x2, y2;
    while (scanf("%d", &n), n) {
        memset(cnt, 0, sizeof cnt);
        memset(qcnt, 0, sizeof qcnt);
        scanf("%d %d %d %d %d", &m, &x1, &y1, &x2, &y2);
        for (int i = 1; i <= n; ++ i) {
            int a, b;
            scanf("%d %d", &a, &b);
            U[i] = Point(a, y1), L[i] = Point(b, y2);
            LU[i - 1] = {L[i], U[i]};
        }
        U[n + 1] = Point(x2, y1), L[n + 1] = Point(x2, y2);
        LU[n] = {L[n + 1], U[n + 1]};
        sort(LU, LU + n);
        
        // for (int i = 0; i <= n; ++ i) {
        //     LU[i].l.output(), LU[i].u.output();
        // }
        // for (int i = 1; i <= m; ++ i) {
        //     int x, y;
        //     scanf("%d %d", &x, &y);
        // }
        
        //for (int i = 0; i <= n; ++ i) LU[i].l.output(), LU[i].u.output();
        
        for (int i = 1; i <= m; ++ i) {
            int x, y;
            scanf("%d %d", &x, &y);
            
            int l = 0, r = n, mid, ans;
            while (l <= r) {
                mid = l + r >> 1;
                Point a = LU[mid].u, b = LU[mid].l;
                if (check(a - b, Point(x, y) - b))
                //if (check(LU[mid].u - LU[mid].l, Point(x, y) - LU[mid]).l))
                    ans = mid, r = mid - 1;
                else l = mid + 1;
            }
            //cout << ans << endl;
            
            cnt[ans] ++ ;
        }
        
         for (int i = 0; i <= n; ++ i) {
        	qcnt[cnt[i]] ++ ;
        	//printf("%d: %d\n", i, cnt[i]);
		}
		printf("Box\n");
		for (int i = 1; i <= m; ++ i) {
			if (qcnt[i])
			printf("%d: %d\n", i, qcnt[i]);
		}
		//printf("\n");
    }
    return 0;
}

枚举暴力

#include <iostream>  
#include <stdio.h>  
#include <string.h>   
#include <stack>  
#include <queue>   
#include <map>  
#include <set>  
#include <vector>  
#include <math.h>  
#include <bitset>  
#include <algorithm>  
#include <climits>

using namespace std;
// `计算几何模板`
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;
//`Compares a double to zero`
int sgn(double x){
	if(fabs(x) < eps)return 0;
	if(x < 0)return -1;
	else return 1;
}
//square of a double
inline double sqr(double x){return x*x;}

struct Point{
	double x,y;
	Point(){}
	Point(double _x,double _y){
		x = _x;
		y = _y;
	}
	void input(){
		scanf("%lf%lf",&x,&y);
	}
	void output(){
		printf("%.2f %.2f\n",x,y);
	}
	bool operator == (Point b)const{
		return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;
	}
	bool operator < (Point b)const{
		return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;
	}
	Point operator -(const Point &b)const{
		return Point(x-b.x,y-b.y);
	}
	//叉积
	double operator ^(const Point &b)const{
		return x*b.y - y*b.x;
	}
	//点积
	double operator *(const Point &b)const{
		return x*b.x + y*b.y;
	}
	//返回长度
	double len(){
		return hypot(x,y);//库函数
	}
	//返回长度的平方
	double len2(){
		return x*x + y*y;
	}
	//返回两点的距离
	double distance(Point p){
		return hypot(x-p.x,y-p.y);
	}
	Point operator +(const Point &b)const{
		return Point(x+b.x,y+b.y);
	}
	Point operator *(const double &k)const{
		return Point(x*k,y*k);
	}
	Point operator /(const double &k)const{
		return Point(x/k,y/k);
	}
	//`计算pa  和  pb 的夹角`
	//`就是求这个点看a,b 所成的夹角`
	//`测试 LightOJ1203`
	double rad(Point a,Point b){
		Point p = *this;
		return fabs(atan2( fabs((a-p)^(b-p)),(a-p)*(b-p) ));
	}
	//`化为长度为r的向量`
	Point trunc(double r){
		double l = len();
		if(!sgn(l))return *this;
		r /= l;
		return Point(x*r,y*r);
	}
	//`逆时针旋转90度`
	Point rotleft(){
		return Point(-y,x);
	}
	//`顺时针旋转90度`
	Point rotright(){
		return Point(y,-x);
	}
	//`绕着p点逆时针旋转angle`
	Point rotate(Point p,double angle){
		Point v = (*this) - p;
		double c = cos(angle), s = sin(angle);
		return Point(p.x + v.x*c - v.y*s,p.y + v.x*s + v.y*c);
	}
};

const int N = 5010;
Point U[N], L[N];
int cnt[N], qcnt[N];

int main() {
    int n, m, x1, y1, x2, y2;
    while (scanf("%d", &n), n) {
        memset(cnt, 0, sizeof cnt);
        memset(qcnt, 0, sizeof qcnt);
        scanf("%d %d %d %d %d", &m, &x1, &y1, &x2, &y2);
        for (int i = 1; i <= n; ++ i) {
            int a, b;
            scanf("%d %d", &a, &b);
            U[i] = Point(a, y1), L[i] = Point(b, y2);
        }
        U[n + 1] = Point(x2, y1), L[n + 1] = Point(x2, y2);
        
        for (int i = 1; i <= m; ++ i) {
            int x, y;
            scanf("%d %d", &x, &y);
            int j = 1, ans;
            double minn = inf;
            for (; j <= n + 1; ++ j) {
                if (sgn((U[j] - L[j]) ^ (Point(x, y) - L[j])) == 1 
				&& sgn(minn - L[j].x) == 1) {
					ans = j;
					minn = L[j].x;
				}
            }
//             cout << ans << "\n";
//             cout << minn << " ";
//             cout << endl;
            cnt[ans - 1] ++ ;
        }
        
        for (int i = 1; i <= n + 1; ++ i) {
        	qcnt[cnt[i - 1]] ++ ;
        	//printf("%d: %d\n", i - 1, cnt[i - 1]);
		}
		printf("Box\n");
		for (int i = 1; i <= m; ++ i) {
			if (qcnt[i])
			printf("%d: %d\n", i, qcnt[i]);
		}
		//printf("\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值