题目大意:

n个点,第i个点和第i+1个点可以构成向量,问最少删除多少个点可以让构成的向量顺时针旋转或者逆时针旋转。

分析:

dp很好想,dp[j][i]表示以向量ji(第j个点到第i个点构成的向量)为终点的最大顺时针/逆时针向量数。状态转移方程为 dp[j][i] = max{dp[k][j]+1}。

问题个关键是如何判断2个向量是顺时针还是逆时针。

计算几何用的知识是求叉积和点积,叉积的作用是判断两个向量的左右(顺逆),点积的作用是判断两个向量的前后。举个例子,假设有2个向量v1,v2,‘*’暂时代表叉积运算,‘·’暂时代表点积运算。叉积判定:如果v1*v2>0,则v1在v2的顺时针方向;如果v1*v2=0,则v1、v2共线;如果v1*v2<0,则v1在v2的逆时针方向。点积判定:如果v1·v2>0,则v1和v2都指向同一侧面;如果v1·v2=0,则v1和v2垂直;如果v1·v2<0,则v1和v2都指向相反的侧面。

顺时针的旋转范围是(0<=T<180),逆时针的旋转范围是(0<T<=180),也就是说如果两条向量共线的话,顺时针旋转可以同方向(T=0),不能反方向;逆时针旋转可以反方向(T=180),不能同方向。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<set>
#include<queue>
#include<stack>
#define MAXN 310 using namespace std;
int dp[MAXN][MAXN],n;
struct Point
{
int x,y;
Point (int x_=,int y_=):x(x_),y(y_) {}
} p[MAXN];
typedef Point Vector;
Vector operator -(Point a,Point b)
{
return Vector(a.x-b.x,a.y-b.y);
}
int Cross(Vector a,Vector b)//向量叉积
{
return a.x*b.y-a.y*b.x;
}
int Dot(Vector a,Vector b)//向量点乘
{
return a.x*b.x+a.y*b.y;
}
int if_shun(int i,int j,int k)//判断顺时针
{ Vector v1=p[i]-p[j];
Vector v2=p[j]-p[k];
int tem=Cross(v1,v2);
if(tem>)
return ;
else if(tem<)
return ;
if(tem==)
{
int tem1=Dot(v1,v2);
if(tem1<)
return ;
return ;
}
}
int if_ni(int i,int j,int k)//判断逆时针
{ Vector v1=p[i]-p[j];
Vector v2=p[j]-p[k];
int tem=Cross(v1,v2);
if(tem>)
return ;
else if(tem<)
return ;
if(tem==)
{
int tem1=Dot(v1,v2);//向量共线,判断一下方向
if(tem1<)
return ;
return ;
}
}
int puan_shun()
{
int ans=;
//dp[0][1]=1;
for(int i=; i<n; i++)
{
for(int j=; j<i; j++)
{
dp[j][i]=;
for(int k=; k<j; k++)
{
if(if_shun(i,j,k))
dp[j][i]=max(dp[j][i],dp[k][j]+);
}
ans=max(ans,dp[j][i]);
} }
return ans;
}
int puan_ni()
{
int ans=;
//dp[0][1]=1;
for(int i=; i<n; i++)
{
for(int j=; j<i; j++)
{
dp[j][i]=;
for(int k=; k<j; k++)
{
if(if_ni(i,j,k))
dp[j][i]=max(dp[j][i],dp[k][j]+);
}
ans=max(ans,dp[j][i]);
} }
return ans;
} int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=; i<n; i++)
scanf("%d %d",&p[i].x,&p[i].y);
memset(dp,,sizeof(dp));
int ans1=puan_shun();
memset(dp,,sizeof(dp));
int ans2=puan_ni();
//printf("%d %d==\n",ans1,ans2);
if(ans1==n-)
printf("C\n");
else if(ans2==n-)
printf("CC\n");
else if(ans1>=ans2)
printf("Remove %d bead(s), C\n",n-ans1-);
else
printf("Remove %d bead(s), CC\n",n-ans2-);
printf("\n");
}
return ;
}

sdut 2153 Clockwise (2010年山东省第一届ACM大学生程序设计竞赛)的更多相关文章

  1. sdut 2159 Ivan comes again!(2010年山东省第一届ACM大学生程序设计竞赛) 线段树+离散

    先看看上一个题: 题目大意是: 矩阵中有N个被标记的元素,然后针对每一个被标记的元素e(x,y),你要在所有被标记的元素中找到一个元素E(X,Y),使得X>x并且Y>y,如果存在多个满足条 ...

  2. 2010年山东省第一届ACM大学生程序设计竞赛 Balloons (BFS)

    题意 : 找联通块的个数,Saya定义两个相连是 |xa-xb| + |ya-yb| ≤ 1 ,但是Kudo定义的相连是 |xa-xb|≤1 并且 |ya-yb|≤1.输出按照两种方式数的联通块的各数 ...

  3. Hello World! 2010年山东省第一届ACM大学生程序设计竞赛

    Hello World! Time Limit: 1000MS Memory limit: 65536K 题目描述 We know that Ivan gives Saya three problem ...

  4. Phone Number 2010年山东省第一届ACM大学生程序设计竞赛

    Phone Number Time Limit: 1000MS Memory limit: 65536K 题目描述 We know that if a phone number A is anothe ...

  5. [2011山东省第二届ACM大学生程序设计竞赛]——Identifiers

    Identifiers Time Limit: 1000MS Memory limit: 65536K 题目:http://acm.sdut.edu.cn/sdutoj/problem.php?act ...

  6. sdut Mountain Subsequences 2013年山东省第四届ACM大学生程序设计竞赛

    Mountain Subsequences 题目描述 Coco is a beautiful ACMer girl living in a very beautiful mountain. There ...

  7. [2012山东省第三届ACM大学生程序设计竞赛]——n a^o7 !

    n a^o7 ! 题目:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2413 Time Lim ...

  8. angry_birds_again_and_again(2014年山东省第五届ACM大学生程序设计竞赛A题)

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2877 题目描述 The problems ca ...

  9. [2012山东省第三届ACM大学生程序设计竞赛]——Mine Number

    Mine Number 题目:http://acm.sdut.edu.cn/sdutoj/problem.php? action=showproblem&problemid=2410 Time ...

随机推荐

  1. [Js]碰撞运动

    描述:撞到目标点弹回来(速度反转) 一.无重力的漂浮div var div1=document.getElementById("div1"); var iSpeedX=6; var ...

  2. S1:运算符

    中括号和小括号的用法: 一般而言,对象中的属性的值是通过点(.)运算符来取值,但是考虑到这样一种情况,我们在遍历一个对象的时候,对其中的属性的键(key)是一无所知的,我们怎么通过点(.)来访问呢?这 ...

  3. if语句使用

    package yuan; public class Yuan { public static void main(String[] args) { int a = 1; int b = 8; int ...

  4. php pthreads 多线程扩展的使用:一个较为稳定例子。

    今天研究了worker stackable的配合方法,写了两种形式,虽然能工作,但是都会出现内存不听增长的问题: 于是把第一个方法的代码邮件给了作者,到现在他没有回复我. 我最后放弃两者配合的方式,直 ...

  5. HDU 4089 Activation 概率DP 难度:3

    http://acm.hdu.edu.cn/showproblem.php?pid=4089 这道题中一共有两个循环: 1.事件1 如果一直落在Activation failed事件上,那么就会重新继 ...

  6. 4通用Makefile编写

    a.c #include<stdio.h> #include "a.h" int main() { printf("hello world\n"); ...

  7. 向量和矩阵的范数及MATLAB调用函数

    范数就是长度的一种推广形式,数学语言叫一种度量.比如有一个平面向量,有两个分量来描述:横坐标和纵坐标.向量的二范数就是欧几里得意义下的这个向量的长度.还有一些诸如极大值范数,就是横坐标或者纵坐标的最大 ...

  8. 凭借K2 SmartObject框架,在SharePoint中集成数据

    随着SharePoint 2013的发布,Microsoft已提供Business Connectivity Services(BCS)增强功能以及外部列表功能,确保您可以更简单地在SharePoin ...

  9. 创建条形码图像易用的控制字符编码功能的条形码控件Native Crystal Reports Barcode Generator

    Native Crystal Reports Barcode Generator是一个对象,它可以很容易地被嵌入到一个Crystal Report中用于创建条形码图像.一旦此条形码被安装在一个报表中, ...

  10. 匹配IP地址的正则表达式 (转)

    正则表达式 ^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[ ...