现在的位置: 首页 > 综合 > 正文

nefu 661 Clockwise 水DP+略几何

2013年11月30日 ⁄ 综合 ⁄ 共 3767字 ⁄ 字号 评论关闭

Clockwise

Time Limit 1000ms

Memory Limit 65536K

description

Saya have a long necklace with N beads, and she signs the beads from 1 to N. Then she fixes them to the wall to show N-1 vectors – vector i starts from bead i and end up with bead i+1.
One day, Kudo comes to Saya’s home, and she sees the beads on the wall. Kudo says it is not beautiful, and let Saya make it better.
She says: “I think it will be better if it is clockwise rotation. It means that to any vector i (i< N-1), it will have the same direction with vector i+1 after clockwise rotate T degrees, while 0≤ T< 180.”
It is hard for Saya to reset the beads’ places, so she can only remove some beads. To saving the beads, although she agrees with Kudo’s suggestion, she thinks counterclockwise rotation is also acceptable. A counterclockwise rotation means to any vector i (i< N-1), it will have the same direction with vector i+1 after counterclockwise rotate T degrees, while 0< T≤ 180.”
Saya starts to compute at least how many beads she should remove to make a clockwise rotation or a counterclockwise rotation.
Since the necklace is very-very long, can you help her to solve this problem?

							

input

The input consists of several test cases.
The first line of input in each test case contains one integer N (2< N ≤ 300), which represents the number of beads.
Each of the next N lines contains two integer x and y, represents the coordinate of the beads. You can assume that 0< x, y< 10000.
The last case is followed by a line containing one zero.

							

output

For each case, print your answer with the following format:
If it is clockwise rotation without removing any beads, please print “C; otherwise if it is counterclockwise rotation without removing any beads, print “CC” instead; otherwise, suppose remove at least x beads to make a clockwise rotation and remove at least y beads to make a counterclockwise rotation. If x≤ y, print “Remove x bead(s), C”, otherwise print “Remove x bead(s), CC” instead.
Your output format should imitate the sample output. Print a blank line after each test case.

							

sample_input

3
1 1
2 2
3 3

3
1 1
2 2
1 1

4
1 1
2 2
3 3
2 2

0

							

sample_output

C
CC
Remove 1 bead(s), C

---------------------------------------

有n个点,已知每个点的坐标。第i个点和第i+1个点组成一个向量,问最少删除多少个点才能使向量顺时针旋转(0<=T<180)或逆时针旋转(0<T<=180)

令f[j,i]表示以点j和i形成的向量为终点的顺时针最长向量数。则f[j,i]=max( f[k,j]+1 )(向量(k,j)向量(j,i)之间为顺时针(0<=T<180))。

剩下的问题就是如何判断两个向量的顺逆时针关系。

PXQ的长度|PQ|=x1*y2 - x2*y1 

PXQ>0则P在Q的顺时针方向。

PXQ<0则P在Q的逆时针方向。

PXQ=0则P与Q共线。

最后是如何判断向量同向还是反向。

若Q在线段P1P2上,则

P1Q与QP2共线,并且Q在以P1P2为对角顶点的矩形内(min(p1x,p2x)<=Qx<=max(p1x,p2x)&&min(p1y,p2y)<=Qy<=max(p1y,p2y))。

--------------------------------------

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int x[333];
int y[333];
int n;
int f[333][333];

bool check1(int i,int j,int k)
{
    int x1=x[i]-x[j];
    int y1=y[i]-y[j];
    int x2=x[j]-x[k];
    int y2=y[j]-y[k];
    if (k==0) return true;
    if (x1*y2-x2*y1==0)
    {
        if (min(x1,x2)<=0&&max(x1,x2)>=0&&min(y1,y2)<=0&&max(y1,y2)>=0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    if (x1*y2-x2*y1>0)
    {
        return true;
    }
    return false;
}

bool check2(int i,int j,int k)
{
    int x1=x[i]-x[j];
    int y1=y[i]-y[j];
    int x2=x[j]-x[k];
    int y2=y[j]-y[k];
    if (k==0) return true;
    if (x1*y2-x2*y1==0)
    {
        if (min(x1,x2)<=0&&max(x1,x2)>=0&&min(y1,y2)<=0&&max(y1,y2)>=0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    if (x1*y2-x2*y1<0)
    {
        return true;
    }
    return false;
}


int main()
{
    while (~scanf("%d",&n))
    {
        if  (n==0) break;
        memset(f,0,sizeof(f));
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        for (int i=1;i<=n;i++)
        {
            scanf("%d%d",&x[i],&y[i]);
        }
        //顺时针
        int ans1=0;
        for (int i=2;i<=n;i++)
        {
            for (int j=1;j<i;j++)
            {
                for (int k=0;k<j;k++)
                {
                    if (check1(i,j,k))
                    {
                        if (f[k][j]+1>f[j][i])
                        {
                            f[j][i]=f[k][j]+1;
                        }
                    }
                    if (f[j][i]>ans1)
                    {
                        ans1=f[j][i];
                    }
                }
            }
        }
        //逆时针
        memset(f,0,sizeof(f));
        int ans2=0;
        for (int i=2;i<=n;i++)
        {
            for (int j=1;j<i;j++)
            {
                for (int k=0;k<j;k++)
                {
                    if (check2(i,j,k))
                    {
                        if (f[k][j]+1>f[j][i])
                        {
                            f[j][i]=f[k][j]+1;
                        }
                    }
                    if (f[j][i]>ans2)
                    {
                        ans2=f[j][i];
                    }
                }
            }
        }
        /*
        for (int i=1;i<=n;i++)
        {
            for (int j=1;j<=n;j++)
            {
                cerr<<f[i][j]<<" ";
            }
            cerr<<endl;
        }
        */
        //cerr<<"-------"<<endl<<ans1<<" "<<ans2<<endl<<"--------"<<endl;
        if (ans1==n-1)
        {
            printf("C\n");
        }
        else if (ans2==n-1)
        {
            printf("CC\n");
        }
        else
        {
            int ans;
            bool ok1=false;
            if (ans1>=ans2)
            {
                ans=ans1;
                ok1=true;
            }
            else
            {
                ans=ans2;
                ok1=false;
            }
            if (ok1)
            {
                printf("Remove %d bead(s), C\n",n-1-ans);
            }
            else
            {
                printf("Remove %d bead(s), CC\n",n-1-ans);
            }
        }
    }
    return 0;
}

抱歉!评论已关闭.