sgu 120 Archipelago

57 篇文章 0 订阅
39 篇文章 0 订阅

120. Archipelago

time limit per test: 0.5 sec.
memory limit per test: 4096 KB

Archipelago Ber-Islands consists of N islands that are vertices of equiangular and equilateral N-gon. Islands are clockwise numerated. Coordinates of island N1 are (x1, y1), and island N2(x2, y2). Your task is to find coordinates of all N islands.

Input

In the first line of input there are N, N1 and N2 (3£N£150, 1£N1,N2£N, N1¹N2) separated by spaces. On the next two lines of input there are coordinates of island N1 and N2 (one pair per line) with accuracy 4 digits after decimal point. Each coordinate is more than -2000000 and less than 2000000.

Output

Write N lines with coordinates for every island. Write coordinates in order of island numeration. Write answer with 6 digits after decimal point.

Sample Input

4 1 3
1.0000 0.0000
1.0000 2.0000

Sample Output

1.000000 0.000000
0.000000 1.000000
1.000000 2.000000
2.000000 1.000000

不得不提高一下自己的计算几何水平,实在是太菜了。
这题我们首先要求出圆心坐标,用一些向量旋转的方法可以减轻代码量。
向量顺时针旋转a度得到的坐标公式:
X=xcos(a)+ysin(a);
Y=-xsin(a)+ycos(a);

反复利用这点,我们就能求出所有的点的坐标。
具体实现代码奉上:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>

#define inf 0xfffffff
#define CLR(a,b) memset((a),(b),sizeof((a)))

using namespace std;
int const nMax = 1000;
int const base = 10;
typedef int LL;
typedef pair<LL,LL> pij;
const double Pi=acos(-1.0);
const double eps=1e-8;

struct Point {
    double x,y;
    Point operator -(Point &b){
        Point c;
        c.x=x-b.x;c.y=y-b.y;
        return c;
    }
    Point operator +(Point &b){
        Point c;
        c.x=x+b.x;c.y=y+b.y;
        return c;
    }
    Point operator *(double k){
        Point c;
        c.x=x*k;c.y=y*k;
        return c;
    }
    double Dis(Point &b){
        return sqrt((x-b.x)*(x-b.x)+(y-b.y)*(y-b.y));
    }
}p[nMax];

struct Line{
    Point a,b;
};

Point Rorate(Point a,Point b,double k,double sita){
    Point ans;
    Point P=b-a;
    ans.x=P.x*cos(sita)+P.y*sin(sita);
    ans.y=-P.x*sin(sita)+P.y*cos(sita);
  //  printf("k=%lf\n",k);
    ans=ans*k;
 //   printf("%lf %lf \n",ans.x,ans.y);
    ans=ans+a;
 //   printf("%lf %lf \n",ans.x,ans.y);

    if(abs(ans.x)<=eps) ans.x=0;
    if(abs(ans.y)<=eps) ans.y=0;
    return ans;
}


int n,n1,n2;

int main(){
    cin>>n>>n1>>n2;
    cin>>p[n1].x>>p[n1].y>>p[n2].x>>p[n2].y;
    int deltaN=abs(n1-n2);
    double sita1=2.0*Pi/n;
    double sita2=Pi-sita1;
    double alfa=sita1*deltaN;
    if(alfa>Pi)alfa=2*Pi-alfa;
    double bata=(Pi-alfa)/2.0;
    if(deltaN>n/2)bata=-bata;
    double dis=p[n1].Dis(p[n2]);
   // printf("sita1=%lf sita2=%lf alfa=%lf bata=%lf dis=%lf\n",sita1,sita2,alfa,bata,dis);
    double r=dis/2.0/sin(alfa/2.0);
  //  printf("r=%lf\n",r);
    Point O=Rorate(p[min(n1,n2)],p[max(n1,n2)],1.0*r/dis,bata);
  //  printf("O= (%lf , %lf ) \n",O.x,O.y);
    int minN=min(n1,n2);
    for(int i=minN+1,ii(minN);;i++){
        ii%=n;
        if(ii==0)ii=n;
        int j=i%n;
        if(j==0)j=n;
        if(j==minN)break;
        p[j]=Rorate(O,p[ii],1,sita1);
        ii=j;
    }
    for(int i=1;i<=n;i++){
        printf("%.6lf %.6lf\n",p[i].x,p[i].y);
    }
    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值