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<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.

输出

 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.

示例输入

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

提示

 

来源

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。
  
  代码:
 #include <iostream>
#include <cmath>
#include <string.h>
using namespace std;
#define eps 1e-10
int dp[][];
/********** 定义点 **********/
struct Point{
double x,y;
Point(double x=,double y=):x(x),y(y) {}
};
Point p[];
/********** 定义向量 **********/
typedef Point Vector;
/********** 点 - 点 = 向量 **********/
Vector operator - (Point a,Point b)
{
return Vector(a.x-b.x,a.y-b.y);
}
/********** 2向量求叉积 **********/
double Cross(Vector a,Vector b)
{
return a.x*b.y-b.x*a.y;
}
/********** 向量点积 **********/
double Dot(Vector a,Vector b)
{
return a.x*b.x+a.y*b.y;
}
bool check1(int i,int j,int k) //核对向量ji是否在向量kj的顺时针方向或者同方向
{
if(k==) return true;
Vector v1 = p[i]-p[j]; //向量ji
Vector v2 = p[j]-p[k]; //向量kj
double x = Cross(v1,v2);
if(fabs(x)<eps){ //向量ji和kj共线,判断一下两向量方向。
double d = Dot(v1,v2);
if(d>eps) //顺时针可以有同方向(0≤T<180)
return true;
else //反方向
return false;
}
else if(x>eps){ //向量ji在向量kj的顺时针方向
return true;
}
return false;
}
bool check2(int i,int j,int k)
{
if(k==) return true;
Vector v1 = p[i]-p[j]; //向量ji
Vector v2 = p[j]-p[k]; //向量kj
double x = Cross(v1,v2);
if(fabs(x)<eps){ //向量ji和kj共线,判断一下两向量方向
double d = Dot(v1,v2);
if(d>eps) //同方向
return false;
else //逆时针可以有反方向(0 < T ≤ 180)
return true;
}
else if(x<eps){ //向量ji在向量kj的逆时针方向
return true;
}
return false;
}
int main()
{
int n;
while(cin>>n){
if(n==) break;
//dp[j][i]表示以向量ji(第j个点到第i个点构成的向量)为终点的最大顺时针向量数
int i,j,k;
for(i=;i<=n;i++) //输入n个点
cin>>p[i].x>>p[i].y;
int r1=,r2=; //最大向量数
//dp
memset(dp,,sizeof(dp));
for(i=;j<=n;i++)
for(j=;j<i;j++){
int Max = ;
for(k=;k<i;k++){
if(check1(i,j,k)){
if(dp[k][j]+>Max)
Max = dp[k][j]+;
}
}
dp[j][i]=Max;
if(dp[j][i]>r1)
r1 = dp[j][i];
}
memset(dp,,sizeof(dp));
for(i=;j<=n;i++)
for(j=;j<i;j++){
int Max = ;
for(k=;k<i;k++){
if(check2(i,j,k)){
if(dp[k][j]+>Max)
Max = dp[k][j]+;
}
}
dp[j][i]=Max;
if(dp[j][i]>r2)
r2 = dp[j][i];
}
if(r1==n-) //向量数比点数少一个
cout<<"C"<<endl;
else if(r2==n-)
cout<<"CC"<<endl;
else if(r1>=r2)
cout<<"Remove "<<n--r1<<" bead(s), C"<<endl;
else
cout<<"Remove "<<n--r2<<" bead(s), CC"<<endl;
cout<<endl;
}
return ;
}

Freecode : www.cnblogs.com/yym2013

sdut 2153:Clockwise(第一届山东省省赛原题,计算几何+DP)的更多相关文章

  1. sdut 2159:Ivan comes again!(第一届山东省省赛原题,STL之set使用)

    Ivan comes again! Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 The Fairy Ivan gave Say ...

  2. sdut 2152:Balloons(第一届山东省省赛原题,DFS搜索)

    Balloons Time Limit: 1000MS Memory limit: 65536K 题目描述 Both Saya and Kudo like balloons. One day, the ...

  3. sdut 2154:Shopping(第一届山东省省赛原题,水题)

    Shopping Time Limit: 1000MS Memory limit: 65536K 题目描述 Saya and Kudo go shopping together.You can ass ...

  4. sdut 2158:Hello World!(第一届山东省省赛原题,水题,穷举)

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

  5. sdut 2162:The Android University ACM Team Selection Contest(第二届山东省省赛原题,模拟题)

    The Android University ACM Team Selection Contest Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里 ...

  6. sdut 2163:Identifiers(第二届山东省省赛原题,水题)

    Identifiers Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述  Identifier is an important c ...

  7. sdut 2165:Crack Mathmen(第二届山东省省赛原题,数论)

    Crack Mathmen Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述  Since mathmen take securit ...

  8. Rectangles(第七届ACM省赛原题+最长上升子序列)

    题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=1255 描述 Given N (4 <= N <= 100)  rec ...

  9. sdut 2153 Clockwise (2010年山东省第一届ACM大学生程序设计竞赛)

    题目大意: n个点,第i个点和第i+1个点可以构成向量,问最少删除多少个点可以让构成的向量顺时针旋转或者逆时针旋转. 分析: dp很好想,dp[j][i]表示以向量ji(第j个点到第i个点构成的向量) ...

随机推荐

  1. 【转发】Visual Studio 2013 如何关闭调试而不关闭IIS Express

    在VS主面板打开:工具->选项->调试->编辑继续   取消选中[启用"编辑并继续"] 就OK了 (英文版的请对应相应的操作) 不过这是针对所有的调试,如果你想针 ...

  2. 〖Linux〗Debian 7.1.0 Wheezy使用ltib报错的解决办法

    报错内容: scue@Link:/home/work/ltib$ ./ltib Processing platform: Phytec board with the NXP LPC32XX SoC = ...

  3. mosquitto配置文件详解

    安装完成之后,所有配置文件会被放置于/etc/mosquitto/目录下,其中最重要的就是Mosquitto的配置文件,即mosquitto.conf,以下是详细的配置参数说明. # Config f ...

  4. Windows下Python添加库(模块)路径

    动态的添加库路径.在程序运行过程中修改sys.path的值,添加自己的库路径 import syssys.path.append(r'your_path') 在Python安装目录下的\Lib\sit ...

  5. 流类库继承体系(IO流,文件流,串流)和 字符串流的基本操作

    一.IO.流 数据的输入和输出(input/output简写为I/O) 对标准输入设备和标准输出设备的输入输出简称为标准I/O 对在外存磁盘上文件的输入输出简称为文件I/O 对内存中指定的字符串存储空 ...

  6. Linux find 命令概览

    Linux下find命令在目录结构中搜索文件,并执行指定的操作.Linux下find命令提供了相当多的查找条件,功能很强大.由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时 ...

  7. BS Web窗体 动态修改WebConfig文件参数及数据库链接串

    WebConfig操作帮助类 /// /// ConfigurationOperator 的摘要说明 /// public class ConfigurationOperator : IDisposa ...

  8. 【Android】15.0 第15章 广播和通知—本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-02-28 一.简介 广播(Broadcast):其功能类似于收音机的广播,你只要调到那个台(只要在接收的类中注册了要接收的广播),就能 ...

  9. Java多线程简析——Synchronized(同步锁)、Lock以及线程池

    Java多线程 Java中,可运行的程序都是有一个或多个进程组成.进程则是由多个线程组成的.最简单的一个进程,会包括mian线程以及GC线程. 线程的状态 线程状态由以下一张网上图片来说明: 在图中, ...

  10. Parallelism , Partitioner

    转:spark通过合理设置spark.default.parallelism参数提高执行效率 spark中有partition的概念(和slice是同一个概念,在spark1.2中官网已经做出了说明) ...