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?
3 1 1 2 2 3 3 3 1 1 2 2 1 1 4 1 1 2 2 3 3 2 2 0
C CC Remove 1 bead(s), C
1 #include <iostream>
2 #include <cmath>
3 #include <string.h>
4 using namespace std; 5 #define eps 1e-10
6 int dp[310][310]; 7 /********** 定义点 **********/
8 struct Point{ 9 double x,y; 10 Point(double x=0,double y=0):x(x),y(y) {} 11 }; 12 Point p[310]; 13 /********** 定义向量 **********/
14 typedef Point Vector; 15 /********** 点 - 点 = 向量 **********/
16 Vector operator - (Point a,Point b) 17 { 18 return Vector(a.x-b.x,a.y-b.y); 19 } 20 /********** 2向量求叉积 **********/
21 double Cross(Vector a,Vector b) 22 { 23 return a.x*b.y-b.x*a.y; 24 } 25 /********** 向量点积 **********/
26 double Dot(Vector a,Vector b) 27 { 28 return a.x*b.x+a.y*b.y; 29 } 30 bool check1(int i,int j,int k) //核对向量ji是否在向量kj的顺时针方向或者同方向
31 { 32 if(k==0) return true; 33 Vector v1 = p[i]-p[j]; //向量ji
34 Vector v2 = p[j]-p[k]; //向量kj
35 double x = Cross(v1,v2); 36 if(fabs(x)<eps){ //向量ji和kj共线,判断一下两向量方向。
37 double d = Dot(v1,v2); 38 if(d>eps) //顺时针可以有同方向(0≤T<180)
39 return true; 40 else //反方向
41 return false; 42 } 43 else if(x>eps){ //向量ji在向量kj的顺时针方向
44 return true; 45 } 46 return false; 47 } 48 bool check2(int i,int j,int k) 49 { 50 if(k==0) return true; 51 Vector v1 = p[i]-p[j]; //向量ji
52 Vector v2 = p[j]-p[k]; //向量kj
53 double x = Cross(v1,v2); 54 if(fabs(x)<eps){ //向量ji和kj共线,判断一下两向量方向
55 double d = Dot(v1,v2); 56 if(d>eps) //同方向
57 return false; 58 else //逆时针可以有反方向(0 < T ≤ 180)
59 return true; 60 } 61 else if(x<eps){ //向量ji在向量kj的逆时针方向
62 return true; 63 } 64 return false; 65 } 66 int main() 67 { 68 int n; 69 while(cin>>n){ 70 if(n==0) break; 71 //dp[j][i]表示以向量ji(第j个点到第i个点构成的向量)为终点的最大顺时针向量数
72 int i,j,k; 73 for(i=1;i<=n;i++) //输入n个点
74 cin>>p[i].x>>p[i].y; 75 int r1=0,r2=0; //最大向量数 76 //dp
77 memset(dp,0,sizeof(dp)); 78 for(i=2;j<=n;i++) 79 for(j=1;j<i;j++){ 80 int Max = 0; 81 for(k=0;k<i;k++){ 82 if(check1(i,j,k)){ 83 if(dp[k][j]+1>Max) 84 Max = dp[k][j]+1; 85 } 86 } 87 dp[j][i]=Max; 88 if(dp[j][i]>r1) 89 r1 = dp[j][i]; 90 } 91 memset(dp,0,sizeof(dp)); 92 for(i=2;j<=n;i++) 93 for(j=1;j<i;j++){ 94 int Max = 0; 95 for(k=0;k<i;k++){ 96 if(check2(i,j,k)){ 97 if(dp[k][j]+1>Max) 98 Max = dp[k][j]+1; 99 } 100 } 101 dp[j][i]=Max; 102 if(dp[j][i]>r2) 103 r2 = dp[j][i]; 104 } 105 if(r1==n-1) //向量数比点数少一个
106 cout<<"C"<<endl; 107 else if(r2==n-1) 108 cout<<"CC"<<endl; 109 else if(r1>=r2) 110 cout<<"Remove "<<n-1-r1<<" bead(s), C"<<endl; 111 else
112 cout<<"Remove "<<n-1-r2<<" bead(s), CC"<<endl; 113 cout<<endl; 114 } 115 return 0; 116 }
Freecode : www.cnblogs.com/yym2013