例题6.18 绿色的世界 UVa11017
来源:互联网 发布:淘宝店长和运营的区别 编辑:程序博客网 时间:2024/05/21 16:23
1.题目描述:点击打开链接
2.解题思路:本题利用Pick定理解决。Pick定理讲的是:给定一个顶点都是整点的简单多边形,其面积A,内部格点的数目I与边上的格点数目B的关系是:A=I+B/2-1。这样,我们就能算出I=A-B/2+1。不过,这样并不能完整的解决本题,因为题目中要求计算每个小菱形的中点有多少个。由于错切变换不会影响内部格点的个数,因此我们不妨仍然理解为在相互垂直的x-y坐标系中,那么等价于要我们找内部x,y坐标的小数部分都是0.5的点有多少个。此时我们可以想办法把它们也都变成“整点”。最直观的办法就是将坐标系顺时针旋转45度,这样,原来的整点还是整点,小数部分均为0.5的点也成了整点。因此,我们可以统计在原坐标系下的内部整点数,再统计坐标系旋转后的内部整点数,后者减去前者就是答案。
3.代码:
#include<iostream>#include<algorithm>#include<cassert>#include<string>#include<sstream>#include<set>#include<bitset>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<cctype>#include<functional>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define me(s) memset(s,0,sizeof(s))#define rep(i,n) for(int i=0;i<(n);i++)typedef long long LL;typedef unsigned int uint;typedef unsigned long long ull;typedef pair <int, int> P;const double PI = acos(-1.0);struct Point { int x, y; Point(int x=0, int y=0):x(x),y(y) { }};typedef Point Vector;Vector operator + (const Vector& A, const Vector& B) { return Vector(A.x+B.x, A.y+B.y); }Vector operator - (const Point& A, const Point& B) { return Vector(A.x-B.x, A.y-B.y); }double Cross(const Vector& A, const Vector& B) { return (LL)A.x*B.y - (LL)A.y*B.x; }LL PolygonArea2(const vector<Point>& p) //计算多边形面积*2的结果{ int n = p.size(); LL area2 = 0; for(int i = 1; i < n-1; i++) area2 += Cross(p[i]-p[0], p[i+1]-p[0]); return abs(area2);}inline int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b);}LL count_on_segment(const Point& a, const Point& b)//计算线段a-b上整点的个数,如果不计算端点,就是gcd(dx,dy)-1个,这不难通过参数表达式得到{ return gcd(abs(b.x-a.x), abs(b.y-a.y)) - 1;}LL count_inside_polygon(const vector<Point>& poly) //利用Pick定理可得:I=A-B/2+1{ int n = poly.size(); LL A2 = PolygonArea2(poly); int B = n; for(int i = 0; i < n; i++) B += count_on_segment(poly[i], poly[(i+1)%n]); return (A2 - B) / 2 + 1;//注意:这里的A2是多边形面积*2的结果,因此也要除以2}LL count(const vector<Point>& poly) //查找x,y小数部分都是0.5的点{ vector<Point> poly2; for(int i = 0; i < poly.size(); i++) poly2.push_back(Point(poly[i].x-poly[i].y, poly[i].x+poly[i].y)); return count_inside_polygon(poly2) - count_inside_polygon(poly); //相减就是答案}int main() { int d, theta, N, x, y; //这里给定的d,theta只是用来计算面积的,错切变换后相当于x-y坐标系下的面积乘以系数d*d*sin(theta) while(scanf("%d%d%d", &d, &theta, &N) == 3 && d) { vector<Point> poly; for(int i = 0; i < N; i++) { scanf("%d%d", &x, &y); poly.push_back(Point(x, y)); } LL area2 = PolygonArea2(poly); printf("%lld %.0lf\n", count(poly), sin((double)theta / 180 * PI) * d * d * area2 / 2.0);//area2/2才是原坐标系的面积 } return 0;}
0 0
- 例题6.18 绿色的世界 UVa11017
- uva11017
- 绿色按钮的制作
- 千锤百炼的绿色PC
- 绿色的希望
- CATIA的绿色安装
- 进击的绿色
- python的绿色版本
- 绿色的数学印象
- 屏幕护眼的绿色
- 世界首辆绿色跑车问世:耗氢气排水汽
- 世界之窗浏览器 6.2.0.124 绿色便携版
- 绿色
- 第66届教育装备展商报道: 让世界更美好,为每个孩子提供一个绿色的云电脑
- fiter 的例题
- 简单的触发器例题
- 关于xml的例题
- 书上的例题
- Bitwise AND of Numbers Range
- log4j.properties 详解与配置步骤
- Qt Style Sheet(六) --- QTextTableCell Class Reference
- 面向“对象”和“过程”
- jsp中<c:forEach varStatus="status">的属性值问题
- 例题6.18 绿色的世界 UVa11017
- 提高Android开发效率的9个Web工具
- EXCEL去重统计(条件去重复计数)
- 使用PHP如何获取WSDL中定义的方法列表
- 7.IOS 8 UIUserNotificationSettings 推送
- poj 2728 Desert King 【最优比例生成树 0-1分数规划】 【二分 or 迭代 + MST】
- Masonry
- 6.UIActionSheet的最后一项点击失效
- C++句柄类