SGU 136 Erasing Edges(计算几何)

Description
顺次给出一个n边形的n条边的中点坐标,问这个n边形是否存在,如果存在,顺次输出n个顶点的坐标,否则输出NO
Input
第一行为一整数n表示边数,之后n行每行两个数表示该条边的中点坐标(3<=n<=10000)
Output
如果该多边形存在则输出YES,并输出n个顶点的坐标,否则输出NO
Sample Input
4
0 0
2 0
2 2
0 2
Sample Output
YES
-1.000 1.000
1.000 -1.000
3.000 1.000
1.000 3.000
Solution
以(x[i],y[i])表示第i个顶点的坐标,以(a[i],b[i])表示第i个顶点与第i+1个顶点的中点坐标,以横坐标为例有
x[1]+x[2]=2*a[1]
x[2]+x[3]=2*a[2]
……
x[n-1]+x[n]=2*a[n-1]
x[n]+x[1]=2*a[n]
考虑前n-1个式子可以得到
x[n]=2*a[n-1]-(2*a[i-2]-(…-(2*a[1]-x[1])))
此时判断x[n]+x[1]是否等于2*a[n]和y[n]+y[1]是否等于2*b[n]即可,当然如果n为偶数时会发现任意(x[1],y[1])都有解
Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<string>
using namespace std;
#define maxn 11111
struct node
{
    double x,y;
    node operator +(const node &a)const
    {
        node b;
        b.x=x+a.x,b.y=y+a.y;
        return b;
    } 
    node operator -(const node &a)const
    {
        node b;
        b.x=x-a.x,b.y=y-a.y;
        return b;
    }
}p[maxn],mid[maxn];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf",&mid[i].x,&mid[i].y);
        if(i&1)p[1]=p[1]+mid[i];
        else p[1]=p[1]-mid[i];
    }
    for(int i=1;i<=n;i++)
        p[i+1]=mid[i]+mid[i]-p[i];
    if(p[n+1].x!=p[1].x||p[n+1].y!=p[1].y)printf("NO\n");
    else
    {
        printf("YES\n");
        for(int i=1;i<=n;i++)
            printf("%.3lf %.3lf\n",p[i].x,p[i].y);
    }
    return 0;
}

你可能感兴趣的:(SGU 136 Erasing Edges(计算几何))