博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sdut 2153:Clockwise(第一届山东省省赛原题,计算几何+DP)
阅读量:7247 次
发布时间:2019-06-29

本文共 4978 字,大约阅读时间需要 16 分钟。

Clockwise

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

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?

输入

The input consists of several test cases.
The first line of input in each test case contains one integer N (2<N300), 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.

输出

 
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 xy, print “Remove x bead(s), C”, otherwise print “Removey bead(s), CC” instead.
Your output format should imitate the sample output. Print a blank line after each test case.

示例输入

31 12 23 331 12 21 141 12 23 32 20

示例输出

CCCRemove 1 bead(s), C

提示

 

来源

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

 
  计算几何 + DP
  题意是给你n个点,第i个点和第i+1个点可以构成向量,问最少删除多少个点可以让构成的向量顺时针旋转或者逆时针旋转。
  思路
  计算几何用的知识是求叉积和点积,这道题可以加深理解这两个计算几何基础知识点的用法。叉积的作用是判断两个向量的左右(顺逆),点积的作用是判断两个向量的前后。举个例子,假设有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都指向相反的侧面。
  DP是用来记录所有可能情况的最大向量数,dp[j][i]表示以向量ji(第j个点到第i个点构成的向量)为终点的最大顺时针/逆时针向量数。状态转移方程为 dp[j][i] = max{dp[k][j]+1}。
  判断如果顺时针逆时针关系可以用叉积,如果共线再用点积判断同方向还是反方向。
 
  注意的点:
  1、规定顺时针的旋转范围是(0<=T<180),逆时针的旋转范围是(0<T<=180),也就是说如果两条向量共线的话,顺时针旋转可以同方向(T=0),不能反方向;逆时针旋转可以反方向(T=180),不能同方向。
  2、如果删掉一定点后,顺时针旋转的最大向量数和逆时针的一样,则取顺时针的值输出。否则会WA。
  
  参考博客:
  代码:
1 #include 
2 #include
3 #include
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) //顺时针可以有同方向(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) //同方向 57 return false; 58 else //逆时针可以有反方向(0 < T ≤ 180) 59 return true; 60 } 61 else if(x
>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
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
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"<
=r2)110 cout<<"Remove "<
<<" bead(s), C"<

 

Freecode :

转载地址:http://tznbm.baihongyu.com/

你可能感兴趣的文章
hdu6376 度度熊剪纸条 思维
查看>>
选择排序模板
查看>>
Ubuntu12.04 Opencv2.4.8 安装笔记
查看>>
[NodeJS] 优缺点及适用场景
查看>>
谈一谈你对js线程的理解
查看>>
div+css 怎么让一个小div在另一个大div里面 垂直居中
查看>>
poj3280(区间dp)
查看>>
DB2创建表、操作表等常用命令
查看>>
Hadoop-2.4.0分布式安装手册
查看>>
二维数组转换成一维数组
查看>>
easyui datagrid 点击表头的事件
查看>>
Web 应用程序项目 Himall.Web 已配置为使用 IIS。 无法访问 IIS 元数据库
查看>>
软件工程人才需求现状与发展现状分析
查看>>
bootstrap插件的一些常用属性介绍
查看>>
MySQL 5.5.35 单机多实例配置详解
查看>>
API 3个 js对象
查看>>
重温数据结构-线性表(王德仙)2012-04-07
查看>>
Java面试官最常问的volatile关键字
查看>>
自动化测试笔记
查看>>
UVA10018 Reverse and Add
查看>>