2010年山东省第一届ACM大学生程序设计竞赛——Clockwise

来源:互联网 发布:买汉服哪家店淘宝 编辑:程序博客网 时间:2024/05/22 06:52

题目链接:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2153

Clockwise

只要理解题目意思,即可敲出正确代码。

题目大意为:给你n个点,让你求出任意一个向量,顺时针旋转180(不能到达180),如果可以达到其余n-2个点,就输出‘C’,逆时针旋转180,如果可以到达n-2个点,就输出‘CC’,如果都不能,看顺时针到达的点数多,还是逆时针达到的点数多,舍弃点数少的一侧。如果两边相等,算作顺时针方向。

用叉乘判断是顺时针方向还是逆时针方向,如果共线,则再利用点乘判断是否符合条件。用dp数组保存最大数。代码如下:

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define eps 1e-9using namespace std;struct point{    double x,y;    point(double x=0,double y=0):x(x),y(y) {}};point p[310];int dp[310][310];typedef point Vector;Vector operator - (point a,point b){    return Vector(a.x-b.x,a.y-b.y);}double cross(Vector a,Vector b){    return a.x*b.y-a.y*b.x;}double dot(Vector a,Vector b){    return a.x*b.x+a.y*b.y;}bool check1(int i,int j,int k){    Vector v1=p[i]-p[j];    Vector v2=p[j]-p[k];    double x=cross(v1,v2);    if(x-eps>0)        return true;    else if(x+eps<0)        return false;    else    {        double d=dot(v1,v2);        if(d+eps<0)            return false;        else            return true;    }}bool check2(int i,int j,int k){    Vector v1=p[i]-p[j];    Vector v2=p[j]-p[k];    int x=cross(v1,v2);    if(x-eps>0)        return false;    else if(x+eps<0)        return true;    else    {        int d=dot(v1,v2);        if(d+eps<0)            return true;        return false;    }}int main(){    int n;    while(scanf("%d",&n),n)    {        int i,j,k;        for(i=0;i<n;i++)            scanf("%lf%lf",&p[i].x,&p[i].y);        int r1=0,r2=0;        memset(dp,0,sizeof(dp));        for(i=0;i<n;i++)            for(j=0;j<i;j++)            {                dp[j][i]=1;                for(k=0;k<j;k++)                    if(check1(i,j,k))                        dp[j][i]=max(dp[j][i],dp[k][j]+1);                r1=max(r1,dp[j][i]);            }        memset(dp,0,sizeof(dp));        for(i=0;i<n;i++)            for(j=0;j<i;j++)            {                dp[j][i]=1;                for(k=0;k<j;k++)                    if(check2(i,j,k))                        dp[j][i]=max(dp[j][i],dp[k][j]+1);                r2=max(r2,dp[j][i]);            }        if(r1==n-1)            printf("C\n");        else if(r2==n-1)            printf("CC\n");        else if(r1>=r2)            printf("Remove %d bead(s), C\n",n-1-r1);        else            printf("Remove %d bead(s), CC\n",n-1-r2);        printf("\n");    }    return 0;}



0 0
原创粉丝点击