zoukankan      html  css  js  c++  java
  • POJ2318 TOYS

    嘟嘟嘟


    题面:先告诉你一个矩形抽屉的坐标,然后(n)个隔板将抽屉分成了(n + 1)格(格子从(0)(n - 1)标号),接下来随机输入(m)个玩具的坐标。问最后每一个格子里有多少个玩具。


    仔细想想就是一道计算几何入门题。
    对于一个玩具((x_0, y_0)),我们只要找到在他的左面且离他最近的隔板(i),则这个玩具就在第(i)格里。
    怎么判断隔板(AB)(规定(A)点是隔板的上端,(B)点是隔板下端)是否在玩具的左边?用叉积即可:只要(overrightarrow{OA} imes overrightarrow{OB} > 0),就说明在左边。
    然后因为有人说从左到右枚举会超时,所以我就把枚举改成倍增了。
    然鹅枚举(O(n ^2))能过呀,于是我就枚举交了一发,也过了……(???)
    代码里注释掉的是枚举的

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define rg register
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 5e3 + 5;
    inline ll read()
    {
    	ll ans = 0;
    	char ch = getchar(), last = ' ';
    	while(!isdigit(ch)) {last = ch; ch = getchar();}
    	while(isdigit(ch)) {ans = (ans << 1) + (ans << 3) + ch - '0'; ch = getchar();}
    	if(last == '-') ans = -ans;
    	return ans;
    }
    inline void write(ll x)
    {
    	if(x < 0) x = -x, putchar('-');
    	if(x >= 10) write(x / 10);
    	putchar(x % 10 + '0');
    }
    
    int n, m, xl, yl, xr, yr; 
    int ans[maxn];
    
    struct Vec
    {
    	int x, y;
    	int operator * (const Vec& oth)const
    	{
    		return x * oth.y - oth.x * y;
    	}
    };
    struct Point
    {
    	int x, y;
    	Vec operator - (const Point& oth)const
    	{
    		return (Vec){x - oth.x, y - oth.y};
    	}
    }ad[maxn], au[maxn], P;
    
    const int N = 13;
    void solve()
    {
    	int L = 0;
    	for(int i = N, t; i >= 0; --i) if((t = L + (1 << i)) <= n)
    	{
    		if((au[t] - P) * (ad[t] - P) > 0) L = t;
    	}
    	/*int L = 0;
    	while(L < n)
    	{
    		if((au[L + 1] - P) * (ad[L + 1] - P) < 0) break;
    		L++;
    	}*/
    	ans[L]++;
    }
    
    int main()
    {
    	while(scanf("%d", &n) && n)
    	{
    		Mem(ans, 0);
    		m = read();
    		xl = read(); yl = read(); xr = read(); yr = read();
    		au[0].y = yl;
    		for(int i = 1; i <= n; ++i) 
    		{
    			au[i].x = read(); au[i].y = yl;
    			ad[i].x = read(); ad[i].y = yr;
    		}
    		for(int i = 1; i <= m; ++i)
    		{
    			P.x = read(); P.y = read();
    			solve();
    		}
    		for(int i = 0; i <= n; ++i) write(i), putchar(':'), space, write(ans[i]), enter;
    		enter;
    	}
    	return 0;
    }
    
  • 相关阅读:
    使用C实现一个函数内两个阿拉伯数字的交换
    使用C比较两个字符串是否相等
    C打印99乘法表
    C定时在控制台输出时分秒
    C实现猜数字
    OpenCV实现开操作、闭操作、形态学梯度、顶帽、黑帽
    OpenCV实现膨胀和腐蚀
    metaclass of python
    Django设计哲学
    using NGINX+uWSGI to deploy django project
  • 原文地址:https://www.cnblogs.com/mrclr/p/9975469.html
Copyright © 2011-2022 走看看