zoukankan      html  css  js  c++  java
  • 2016级算法第六次上机-A.Bamboo之寻找小金刚

    Bamboo之寻找小金刚

    分析

    可以抽象为许多连续线段,分别计数左拐和右拐的个数。考察叉积的基础应用。
    假设ABC三点构成一个夹角∠ABC,B就是拐点,AC是辅助形成夹角。考虑线段AB和BC形成的向量

    sin∠ABC= (AB * BC)/|AB|*|BC|

    两个向量的叉乘除以它们的模
    所以叉乘可以判断夹角是否大于180°从而确定转向。当然叉积是有方向的,可以自己选择哪条边在前,只要标准统一即可。每三个点组成一组,遍历,分别计数左拐数和右拐数。具体叉积相关操作可以看《算法导论》

    注意

    常见的一种陷阱是给出的数据范围明确在int范围内,但是计算过程中+-*/尤其是+-,是很可能导致数据暂时超出int范围的,所以建议用long long,或者计算时强制转化为long long
    另外观察n的范围1<n,有一组只有两个点的边界情况,此时没有拐点

    代码

    const int maxx = 1e6 + 5;
    struct point{
    	long long x, y;
    }p[maxx];
    long long dir(point pi, point pj, point pk)
    {
    	return (pk.x - pi.x)*(pj.y - pi.y) - (pj.x - pi.x)*(pk.y - pi.y);
    }
    int main()
    {
    	int n, a;
    	while (~scanf("%d%d", &n, &a))
    	{
    		for (int i = 0; i<n; i++)
    		{
    			scanf("%lld %lld", &p[i].x, &p[i].y);
    		}
    		long long left = 0, right = 0;
    		long long ans = a, temp;
    		if (n<3)ans = a;
    		else{
    			for (int i = 2; i<n; i++)
    			{
    				temp = dir(p[i - 2], p[i - 1], p[i]);
    				//printf("i=%d,temp =%d
    ",i,temp);
    				if (temp<0){ left++; ans += left; }
    				else if (temp>0){ right++; ans -= right; }
    			}
    		}
    		printf("%lld
    ", ans);
    	}
    }
    
  • 相关阅读:
    (转)tomcat 安全配置文档
    (转)nginx 安全配置文档
    (转)scipy详解
    (转)matplotlib实战
    (转)Python3的四舍五入round()函数坑爹?不,更科学!
    (转)p解决 java.util.prefs.BackingStoreException 报错问题
    (转)asyncio --- 异步 I/O
    (转)pycharm快捷键、常用设置、配置管理
    (转)db2top详解
    (转)Db2 数据库常见堵塞问题分析和处理
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/8185347.html
Copyright © 2011-2022 走看看