• 原题如下:

    Suppose that P1 is an infinite-height prism whose axis is parallel to the z-axis, and P2 is also an infinite-height prism whose axis is parallel to the y-axis. P1 is defined by the polygon C1 which is the cross section of P1 and the xy-plane, and P2is also defined by the polygon C2 which is the cross section of P2 and the xz-plane.

    Figure I.1 shows two cross sections which appear as the first dataset in the sample input, and Figure I.2 shows the relationship between the prisms and their cross sections.

    Figure I.1: Cross sections of Prisms

    Figure I.2: Prisms and their cross sections

    Figure I.3: Intersection of two prisms

    Figure I.3 shows the intersection of two prisms in Figure I.2, namely, P1 and P2.

    Write a program which calculates the volume of the intersection of two prisms.

    Input

    The input is a sequence of datasets. The number of datasets is less than 200.

    Each dataset is formatted as follows.

    m n
    x11 y11
    x12 y12 
    .
    .
    .
    x1m y1m 
    x21 z21
    x22 z22
    .
    .
    .
    x2n z2n

    m and n are integers (3 ≤ m ≤ 100, 3 ≤ n ≤ 100) which represent the numbers of the vertices of the polygons, C1 and C2, respectively.

    x1iy 1 ix 2j and z 2j are integers between -100 and 100, inclusive. ( x 1iy 1i) and ( x 2j , z 2j) mean the i-th and j-th vertices' positions of C 1 and C 2respectively.

    The sequences of these vertex positions are given in the counterclockwise order either on the xy-plane or the xz-plane as in Figure I.1.

    You may assume that all the polygons are convex, that is, all the interior angles of the polygons are less than 180 degrees. You may also assume that all the polygons are simple, that is, each polygon's boundary does not cross nor touch itself.

    The end of the input is indicated by a line containing two zeros.

    Output

    For each dataset, output the volume of the intersection of the two prisms, P1 and P2, with a decimal representation in a line.

    None of the output values may have an error greater than 0.001. The output should not contain any other extra characters.

    Sample Input

    4 3
    7 2
    3 3
    0 2
    3 1
    4 2
    0 1
    8 1
    4 4
    30 2
    30 12
    2 12
    2 2
    15 2
    30 8
    13 14
    2 8
    8 5
    13 5
    21 7
    21 9
    18 15
    11 15
    6 10
    6 8
    8 5
    10 12
    5 9
    15 6
    20 10
    18 12
    3 3
    5 5
    10 3
    10 10
    20 8
    10 15
    10 8
    4 4
    -98 99
    -99 -99
    99 -98
    99 97
    -99 99
    -98 -98
    99 -99
    96 99
    0 0
    

    Output for the Sample Input

    4.708333333333333
    1680.0000000000005
    491.1500000000007
    0.0
    7600258.4847715655
  • 题解:朴素想法,求出公共部分的凸多面体的顶点坐标,然后再计算其体积。公共部分的凸多面体的顶点都是一个棱柱的侧面与另一个棱柱的侧棱的交点,可以通过O(nm)时间的枚举求得,但因为涉及三维空间的几何运算,实现起来是非常麻烦的。
    事实上,沿x轴对棱柱切片即可:按某个值对侧棱与z轴平行的棱柱P1切片后,就得到了[y1,y2]*(-∞,∞)这样的在z轴方向无限延伸的长方形的横截面,同样的,我们按某个x值对侧棱与y轴平行的棱柱P2切片后,就得到了(-∞,∞)*[z1,z2]这样的在y轴方向无限延伸的长方形的横截面。因此,我们按某个x值对两个棱柱的公共部分切片后,得到的横截面就是长方形[y1,y2]*[z1,z2]。而长方形的面积通过(y2-y1)*(z2-z1)就可以求得,关于x轴对面积求积分就能得到公共部分的体积了。
    首先,枚举出原棱柱底面顶点的所有x坐标并排序,在相邻两个x坐标之间的区间中按x值切片得到的长方形的顶点坐标是关于x的线性函数,所以面积就是关于x的二次函数,其积分很容易计算,虽然可以通过求得表达式后再来计算二次函数的积分,但应用Simpson公式则更为轻松。Simpson公式如下:

    Simpson公式就是在数值积分中用二次函数来近似原函数进行积分而得到的公式,如果原函数本身就是次数不超过二的多项式,那么用Simpson公式就可以得到精确的积分值。利用该公式,无需求出关于x的多项式,而只要计算按区间的端点和中点切片得到的长方形的面积就够了。

  • 代码:
    #include<cstdio>
    #include<algorithm>
    #include<vector>using namespace std;const int INF=0x3f3f3f3f;
    const double EPS=1e-10;
    const int MAX_N=500;
    int N,M;
    int X1[MAX_N], Y1[MAX_N], X2[MAX_N], Z2[MAX_N];double max(double x, double y)
    {if (x>y+EPS) return x;return y;
    }double min(double x, double y)
    {if (x<y-EPS) return x;return y;
    }double width(int * X, int * Y, int n, double x)
    {double lb=INF, ub=-INF;for (int i=0; i<n; i++){double x1=X[i], y1=Y[i], x2=X[(i+1)%n], y2=Y[(i+1)%n];if ((x1-x)*(x2-x)<=0 && x1!=x2){double y=y1+(y2-y1)*(x-x1)/(x2-x1);lb=min(lb, y);ub=max(ub, y);}}return max(0.0, ub-lb);
    }int main()
    {while (~scanf("%d %d", &M, &N)){if (M==0 && N==0) break;for (int i=0; i<M; i++){scanf("%d %d", &X1[i], &Y1[i]);}for (int i=0; i<N; i++){scanf("%d %d", &X2[i], &Z2[i]);}int min1=*min_element(X1, X1+M), max1=*max_element(X1, X1+M);int min2=*min_element(X2, X2+N), max2=*max_element(X2, X2+N);vector<int> xs;for (int i=0; i<M; i++) xs.push_back(X1[i]);for (int i=0; i<N; i++) xs.push_back(X2[i]);sort(xs.begin(), xs.end());double res=0;for (int i=0; i+1<xs.size(); i++){double a=xs[i], b=xs[i+1], c=(a+b)/2;if (min1<=c && c<=max1 && min2<=c && c<=max2){double fa=width(X1, Y1, M, a)*width(X2, Z2, N, a);double fb=width(X1, Y1, M, b)*width(X2, Z2, N, b);double fc=width(X1, Y1, M, c)*width(X2, Z2, N, c);res+=(b-a)/6*(fa+4*fc+fb);}}printf("%.10f\n", res);}
    }

转载于:https://www.cnblogs.com/Ymir-TaoMee/p/9791543.html

Intersection of Two Prisms(AOJ 1313)相关推荐

  1. UVALive 5075 Intersection of Two Prisms(柱体体积交)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  2. linux中scp -r命令,linux:scp从入门到刚入门

    Objective-C 关联 在项目开发中,经常会使用到关联,就是将两个实例对象绑定,使得其中一个实例对象成为另一个实例对象的一部分.关联特性在mac os 10.6 及ios 3.1以上才可以使用. ...

  3. CF 1093 E. Intersection of Permutations

    E. Intersection of Permutations 链接 题意: 给定两个序列,询问第一个排列的[l1,r1]和第二个排列[l2,r2]中有多少个共同的数,支持在第二个排列中交换两个数. ...

  4. 【leetcode75】Intersection of Two Arrays(数组的交集)

    题目描述: 给定两个数组求他们的公共部分,输出形式是数组,相同的元素只是输出一次 例如: nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2]. 原文描述: ...

  5. 一个Apache CollectionUtils.intersection 方法的简单问题

    2019独角兽企业重金招聘Python工程师标准>>> 今天在使用CollectionUtils.intersection()  的时候,发现个问题,明明两个集合中有几个完全相同的类 ...

  6. WOJ 1313 - K尾相等数

    原题网址:Problem 1313 - K尾相等数 Description 从键盘输入一个自然数K(K>1),若存在自然数M和N(M>N),使得K^M和K^N均大于或等于1000.且它们的 ...

  7. Python计算两个numpy数组的交集(Intersection)实战:两个输入数组的交集并排序、获取交集元素及其索引、如果输入数组不是一维的,它们将被展平(flatten),然后计算交集

    Python计算两个numpy数组的交集(Intersection)实战:两个输入数组的交集并排序.获取交集元素及其索引.如果输入数组不是一维的,它们将被展平(flatten),然后计算交集 目录

  8. python 集合set 的三大方法intersection union difference来处理文氏图

    TODO - 练习:A或B,但不能同时包含 编写一个函数,将两个集合(set_a和set_b)作为输入,并返回一个新的集合,其中包含set_a或set_b中的元素,但不包含两者兼有的元素. 在上面的文 ...

  9. Leetcode: Intersection of Two Arrays

    Given two arrays, write a function to compute their intersection.Example: Given nums1 = [1, 2, 2, 1] ...

  10. Intersection of Two Linked Lists——经典问题

    Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...

最新文章

  1. 数字证书及网络加解密原理
  2. Linux内核学习笔记
  3. Heap(堆结构/优先队列)-Swift实现
  4. RAC的搭建(一)--安装环境准备
  5. Django之URLconf路由
  6. LeetCode 413. 等差数列划分(DP)
  7. 软件工程复习提纲——第一章
  8. 想快速重构智慧园区5A系统,这份方案推荐给你
  9. linux内核启动文件系统,Linux启动过程中文件系统的加载
  10. asp 禁止某一个目录_asp.net core 系列 10 配置configuration (上)
  11. 基于 Vue 的轻量级静态网站生成器 VuePress
  12. 基于预训练语言模型的文本生成研究综述
  13. IOS:static和extern的使用
  14. rainmeter 修正天气插件信息不准确 设置居住城市
  15. 医院信息系统等级保护
  16. Python爬虫入门教程 25-100 知乎文章图片爬取器之一
  17. 48.XML保存衣服尺码信息
  18. 为什么大数据与云计算密不可分?
  19. 用了几年的iPhone 11竟然可以免费换电池
  20. C#基础(10)——飞行棋游戏

热门文章

  1. Spring源码之ApplicationContext(二)准备工作
  2. 【渝粤教育】国家开放大学2018年春季 0275-21T内科护理学 参考试题
  3. 数据预处理第2讲:非线性变换
  4. 【5分钟 Paper】Deep Reinforcement Learning with Double Q-learning
  5. 【详细原理】蒙特卡洛树搜索入门教程!
  6. 使用git软件上传文件到自己的github当中去
  7. PyQt 的程序框架——面向对象版本
  8. HashMap和HashSet的区别?
  9. git学习中遇到的疑难杂症
  10. javascript traverse object attributes 遍历对象属性