2018/7/26 22:33
首先就是关于对向量的操作,一般是用结构体储存x,y,这样方便在结构体中重载操作符,使得可以十分方便的进行数学中的一些向量操作,下面就附上关于"+,-乘"
struct Pt
{
int x, y;
Pt (){}//先声明函数,也是构造函数,没有这一步,一下的操作会报错;
Pt(int _x, int _y)
{
x = _x;//这一步的操作是声明你参数里面的x就是结构体的x你的那个y也是结构体的y;
y = _y;
}
Pt operator - ( Pt b) {//这里的x就是‘-’号前面的那个结构体,下同;
return Pt(x - b.x, y - b.y);
}
Pt operator + ( Pt b) {
return Pt(x + b.x, y + b.y);
}
Pt operator * (double a)
{
return Pt(x*a, y*a);
}
};
下面是向量的点积和矢积:
double dot(Pt a, Pt b)
{
return a.x*b.x + a.y*b.y;
}
double det(Pt a, Pt b)//别忘了矢积也是有方向的,右手定则,右手手指顺着第一个向量的方向指向第二个向量的方向,默认垂直直面向上为正方向;
{
return a.x*b.y - b.x*a.y;
}
设点c,直线ab
所以矢量ac和cb的叉乘为0==在直线上
可以使用如下方法:1,判断叉乘为0,且点c在线段ab为对角线的矩阵内
代码
bool PtOnSegment(Pt s, Pt t, Pt a) {
return !det(a-s,a-t)&&min(s.x,t.x)<=a.x &&
a.x<=max(s.x,t.x)&&min(s.y, t.y) <= a.y &&
a.y <= max(s.y, t.y);
若两个条件都满足,那么则两个线段相交;
原理其实就是顶点相连把多边形分成三角形,然后利用叉乘来计算三角形面积,然后累加即可,此方法可适用凹凸多边形,对于凸多边形无需多言,而对于凹多边形,其实根据叉乘的正负性,是可以消掉多出的那部分三角形;
代码实现
double PolygonArea(Pt* p,int n){
double area =0;
for(int i=1;i
int polygon_border_point_cnt(const Polygon &p) {//伪代码不要直接粘贴;
int ans = 0;
int n = p.size();//p.size()表示的是p的定点数
for (int i = 0; i < n; ++i)
ans += gcd(Abs(int(p[next(i)].x-p[i].x)),//next(i)表示i下面一个点;
Abs(int(p[next(i)].y-p[i].y)));
return ans;
}
//其实,仔细品味代码,可以看出这段代码的意思就是求这个线段在水平方向的长度和竖直长度上的值的最大公约数
代码实现
int ConvexHull(Point* p,int n,Point* ch){//p为输入数组,也就是一开始存放坐标的结构体,ch就是最后得到的凸包的坐标数组
sort(p,p+n,cmp); int m=0;
for(int i=0;i1&&det(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-2;i>=0;i--){
while(m>k&&det(ch[m-1]-ch[m-2],
p[i]-ch[m-2])<=0) m--;
ch[m++]=p[i];
}
if(n>1) m--;
return m;
}
这次的题只贴出四道题,前两道超出了本次的内容,后天补上,最后三道题太过于简单,唯一值得一写的就是对于一个直线和另一个直线相交,最多会产生(n-1)个交点,那么就会产生(n-1)+1个平面;所以可得到一个递推式f(n)=f(n-1)+(n-1)+1;fn表示n个直线所产生的平面
Your friend to the south is interested in building fences and turning plowshares into swords. In order to help with his overseas adventure, they are forced to save money on buying fence posts by using trees as fence posts wherever possible. Given the locations of some trees, you are to help farmers try to create the largest pasture that is possible. Not all the trees will need to be used.
However, because you will oversee the construction of the pasture yourself, all the farmers want to know is how many cows they can put in the pasture. It is well known that a cow needs at least 50 square metres of pasture to survive.
Input
The first line of input contains a single integer, n (1 ≤ n ≤ 10000), containing the number of trees that grow on the available land. The next n lines contain the integer coordinates of each tree given as two integers x and y separated by one space (where -1000 ≤ x, y ≤ 1000). The integer coordinates correlate exactly to distance in metres (e.g., the distance between coordinate (10; 11) and (11; 11) is one metre).
Output
You are to output a single integer value, the number of cows that can survive on the largest field you can construct using the available trees.
Sample Input
4 0 0 0 101 75 0 75 101
Sample Output
151
代码
#include
#include
#include
#include
using namespace std;
struct summer//老规矩,用结构体存坐标;
{
int x;
int y;
summer (){}
summer(int _x,int _y)
{
x=_x;
y=_y;
}
summer operator -(const summer &b)
{
return summer (x-b.x,y-b.y);
}
}oj[10005];
int det(summer a,summer b)//用来计算叉乘
{
return a.x*b.y-b.x*a.y;
}
summer ac[10005];
bool com(summer a,summer b)//还记得吗?在计算凸包时,是要排序的哦!;
{
if(a.x==b.x) return a.y1&&det(ch[m-1]-ch[m-2],p[i]-ch[m-2])<0)
m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-2;i>=0;i--)
{
while(m>k&&det(ch[m-1]-ch[m-2],p[i]-ch[m-2])<0) m--;
ch[m++]=p[i];
}
if(n>1) m--;
return m;
}
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
for(int i=0;i>oj[i].x>>oj[i].y;
}
int re= f(oj,n,ac);
int ans=mianji(ac,re);
cout<
Being well known for its highly innovative products, Merck would definitely be a good target for industrial espionage. To protect its brand-new research and development facility the company has installed the latest system of surveillance robots patrolling the area. These robots move along the walls of the facility and report suspicious observations to the central security office. The only flaw in the system a competitor抯 agent could find is the fact that the robots radio their movements unencrypted. Not being able to find out more, the agent wants to use that information to calculate the exact size of the area occupied by the new facility. It is public knowledge that all the corners of the building are situated on a rectangular grid and that only straight walls are used. Figure 1 shows the course of a robot around an example area.
Figure 1: Example area.
You are hired to write a program that calculates the area occupied by the new facility from the movements of a robot along its walls. You can assume that this area is a polygon with corners on a rectangular grid. However, your boss insists that you use a formula he is so proud to have found somewhere. The formula relates the number I of grid points inside the polygon, the number E of grid points on the edges, and the total area A of the polygon. Unfortunately, you have lost the sheet on which he had written down that simple formula for you, so your first task is to find the formula yourself.
Input
The first line contains the number of scenarios.
For each scenario, you are given the number m, 3 <= m < 100, of movements of the robot in the first line. The following m lines contain pairs 揹x dy�of integers, separated by a single blank, satisfying .-100 <= dx, dy <= 100 and (dx, dy) != (0, 0). Such a pair means that the robot moves on to a grid point dx units to the right and dy units upwards on the grid (with respect to the current position). You can assume that the curve along which the robot moves is closed and that it does not intersect or even touch itself except for the start and end points. The robot moves anti-clockwise around the building, so the area to be calculated lies to the left of the curve. It is known in advance that the whole polygon would fit into a square on the grid with a side length of 100 units.
Output
The output for every scenario begins with a line containing 揝cenario #i:� where i is the number of the scenario starting at 1. Then print a single line containing I, E, and A, the area A rounded to one digit after the decimal point. Separate the three numbers by two single blanks. Terminate the output for the scenario with a blank line.
Sample Input
2 4 1 0 0 1 -1 0 0 -1 7 5 0 1 3 -2 2 -1 0 0 -3 -3 1 0 -3
Sample Output
Scenario #1: 0 4 1.0 Scenario #2: 12 16 19.0
大概思路还是pick定理
代码
#include
#include
#include
#include
using namespace std;
struct summer
{
int x,y;
summer(){}
summer(int _x,int _y)
{
x=_x;
y=_y;
}
summer operator -(const summer &b)const
{
return summer (x-b.x,y-b.y);
}
}oj[102];
int det(summer a,summer b)
{
return a.x*b.y-b.x*a.y;
}
double mianji(summer *p,int n)
{
double ans=0;
for(int i=1;i>n;
while(n--)
{
p++;
int m,x=0,y=0,x1,y1;
cin>>m;
double ans=0;
int ans2=0,ans1=0;
for(int i=1;i<=m;i++)
{
cin>>x1>>y1;
ans2+=gcd(abs((double)x1),abs((double)y1));
oj[i].x=x+x1;
oj[i].y=y+y1;
x+=x1;
y+=y1;
}
ans=mianji(oj,m);
ans1=(ans+1-ans2/2);
printf("Scenario #%d:\n",p);
printf("%d %d %.1f\n",ans1,ans2,ans);
puts("");
}
return 0;
}
还剩下一道D题,回来跟昨天的一个博客一起补吧,太困了。