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;
}