《训练指南》——8.3

LA3263:

题目大意:给出一个一笔画图形,它包含n个点。先给出其n个点坐标之后,求解这个图形把平面分成了几个区域。

分析:这里要求的是面的个数,显然连直接暴力进行求解的方法都没有,因此这里就需要进行一定的转化,已知信息是点的坐标,那么我们应该能够想到平面几何中的欧拉定理(我们将图形看成图论当中的图G),经过这一步转换,我们需要做的就是求解图形的点数和边数。

点:显然这里我们就需要设置暴力,以确保能够完成所有相交情况的筛查。穷举之后,原来的节点数加交点数(去重后)就是该图中的总结点数v.

边:结合欧拉定理的适用条件,这里需要注意的是“边”的两个节点的直接连线。

简单的参考代码如下(时间原因未调试):

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps = 1e-10;
struct Point
{
    double x , y;
    Point(double x = 0 , double y = 0):x(x),y(y){};//定义点的时候直接利用构造函数,很方便
};
typedef Point Vector;//这里因为向量都有两个维度的有序参量

Vector operator + (Vector A,Vector B){return Vector(A.x+B.x , A.y+B.y);}
Vector operator - (Point A,Point B)  {return Vector(A.x-B.x , A.y-B.y);}
Vector operator * (Vector A,double p){return Vector(A.x*p , A.y*p);}
Vector operator / (Vector A,double p){return Vector(A.x/p , A.y/p);}

int dcmp(double x)
{
    if(fabs(x) < eps) return 0;
    else              return x < 0 ? -1 :1;
}
double Cross(Vector A , Vector B)//向量叉积
{
    return A.x * B.y - A.y * B.x;
}

const int maxn = 310;
Point P[maxn] , V[maxn*maxn];
bool SegmentProperIntersection(Point a1 , Point a2 , Point b1 , Point b2)
{
    double c1 = Cross(a2 - a1 , b1 - a1);
    double c2 = Cross(a2 - a1 , b2 - a1);
    double c3 = Cross(b2 - b1 , a1 - b1);
    double c4 = Cross(b2 - b1 , a2 - b1);

    return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3)*dcmp(c4) < 0;
}
Point GetLineIntersection(Point P , Vector v , Point Q , Vector w)
{
    Vector u = P-Q;
    double t = Cross(w , u) / Cross(v , w);
    return P + v*t;
}
double Dot(Vector A , Vector B){return A.x*B.x + A.y*B.y;}
bool OnSegment(Point p , Point a1 , Point a2)
{
     return dcmp(Cross(a1 - p,a2 - p)) == 0 && dcmp(Dot(a1 - p , a2 - p)) < 0;
}
int main()
{
     int n , kase = 0;
     while(scanf("%d",&n) == 1 &&n)
     {
          for(int i = 0;i < n;i++){scanf("%lf%lf",&P[i].x,&P[i].y);V[i] = P[i];}
          n--;
          int c = n , e = n;
          for(int i = 0;i < n;i++)
              for(int j = i + 1;j < n;j++)
                if(SegmentProperIntersection(P[i],P[i+1],P[j],P[j+1]))
                      V[c++] = GetLineIntersection(P[i], P[i+1] - P[i],P[j] , P[j+1]-P[j]);
        sort(V , V + c);
        c = unique(V , V + c) - V;

        for(int i = 0;i < c;i++)
              for(int j = 0;j < n;j++)
                  if(OnSegment(V[i],P[j],P[j+1])) e++;
        printf("Case %d: There are %d piece s.\n",++kase , e+ 2 - c);
     }
     return 0;
}
时间: 2024-08-07 21:18:01

《训练指南》——8.3的相关文章

计算几何-圆 模板 训练指南267

#include #include #include #include #include #include #include #include #include #include #define MM(a) memset(a,0,sizeof(a)) typedef long long ll; typedef unsigned long long ULL; const double eps = 1e-10; const int inf = 0x3f3f3f3f; using namespace

《训练指南》——6.13

困于时间缘故和考试缠身,笔者在先前关于<训练指南>的而第二章的数学基础的介绍先告一段落,开始对第一章简单的一些算法基础题目进行介绍. Uva11292: 你的王国里有一条n个头的恶龙,你希望雇一些其实把它杀死(即砍掉所有的头).村里有m个其实可以雇佣,一个能力值为x的其实可以砍掉恶龙一个半径不超过x的头,且需要支付x个金币.如何雇佣其实才能砍掉恶龙的所有头,且需要支付的金币最少?注意,一个其实只能看一个头(且只能被雇用一次). 分析:观察到题目给出支付最少的字眼,我们容易将其往动态规划或者贪心

Uva10881-算法入门经典训练指南

算法入门经典训练指南 第一章例题5 这道题个人感觉还是很有技术含量的,如果纯模拟可以搞死人. 这里面的一个蚂蚁在碰撞而掉头的情形,最后被看做是“对穿而过”,这种“转换思想”是非常厉害滴..要是我有一天也有这种技能就好了 个人感觉如果看不出来,这道题就挂了. 所以在处理复杂问题上的时候,如果直接去做很复杂.很麻烦,那就应该想办法变通,比如像这道题目,我们寻找共同点,于是发现,他们的方向始终相反,速度始终相同,那么就可以看作是一毛一样地蚂蚁. 当然处理完了之后,还有一些小细节,比如所有蚂蚁的相对位置

算法竞赛入门经典训练指南

最近在看算法竞赛入门经典训练指南这本书,书中不错的算法我将在博客中发布,和大家共同学习. 题目: 在你的王国里有一条n个头的恶龙,你希望雇一些骑士把它杀死(即砍掉所有头).村里有m个骑士可以雇佣,一个能力值为m的骑士可以砍掉一个直径不超过x的头,且需要支付x个金币.如何雇佣骑士才能砍掉恶龙的所有头,且需要支付的金币最少?注意,一个骑士只能砍一个头(且不能被雇佣两次). 输入格式: 输入包含多组数据.每组数据的第一行为正整数m和n(1<=m,n<=20 000):以下m行每行为一个整数,即恶龙每

算法竞赛入门经典-训练指南(10881-Piotr&#39;s Ants)

题目大意: 一根长度为L的木棍一堆蚂蚁爬,向左或向右,速度都为1,若两蚂蚁碰撞则同时转头(转身时间忽略不计),问T时间之后每只蚂蚁的位置: 输入:t,(t个样例),每个样例输入 L,T,n,接下来是n行每行两个数据,一个POS(位置),一个dir(方向): 输出:按输入顺序输出每只蚂蚁的最终位置,若处于碰撞状态则输出Turning,掉下去输出"Fell off": 解题思路: 本题类似于<挑战程序设计>的一道水题(POJ -1852  Ants),思路题:不过本题输入并不一

训练指南DP阶段训练1

最近又忙又颓.............时间抓不紧....下学期开始就要准备考研了.......就2个月左右可以做自己喜欢的事了....争取把紫书和白书没做的,做过的..来一次完整的总结 训练指南上面的5个例题+后面15个习题是第一阶段 vjudge训练地址 http://vjudge.net/contest/139533#overview -------------------------------------------------------------------------------

Trie树基本概念和训练指南

接触Trie树是在选拔赛时候遇到一题目,TLE无数次依然无解,赛后发现字符串统计有一利器名曰"字典树",后来花了一段时间去写Trie,算是基本入门了. 本文主要是介绍一些基本概念,以及一些训练题目,提供大家. 什么叫Trie树? Trie树即字典树. 又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字

【UVA11107 训练指南】Life Forms【后缀数组】

题意 输入n(n<=100)个字符串,每个字符串长度<=1000,你的任务是找出一个最长的字符串使得超过一半的字符串都包含这个字符串. 分析 训练指南上后缀数组的一道例题,据说很经典(估计也就是height分组比较常用).但是训练指南上给出的中文题面真滴坑B啊!书上说,连续出现,我懵逼了好久! 我们把这n个字符串连成一个长的字符串S,且中间用不同的未出现的字符相隔开(为什么隔开我们后面说),比如样例一会变为abcdefg1bcdefgh2cdefghi3.这样每一段是一个原字符串.然后问题转换

训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板)

layout: post title: 训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - Dijkstra - 图论 - 训练指南 Airport Express UVA - 11374 题意 机场快线有经济线和商业线,现在分别给出经济线和商业线的的路线,现在只能坐一站商业线,其他坐经济线,问从起点到终点的最短用时是多少,还有

训练指南 UVA - 10917(最短路Dijkstra + 基础DP)

layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - 基础DP - Dijkstra - 图论 - 训练指南 Walk Through the Forest UVA - 10917 题意 Jimmy打算每天沿着一条不同的路走,而且,他只能沿着满足如下条件的道路(A,B):存在一条从B出发回家的路径,比