POJ 1921 Paper Cut(计算几何の折纸问题)
Description
Carol's puzzle is simple to state. She folds the paper in a certain manner and then uses a knife to cut through the folded paper. What Mike needs to do is to tell how many pieces the folded paper will turn into after it is cut. To eliminate the ambiguity, we can coordinate the paper as [0, 1] * [0, 1], with the coordinates of lower left corner (0, 0). A fold is denoted by two points (x1, y1) and (x2, y2) on the folding line, with which, the direction of the line is determined by from (x1, y1) to (x2, y2). Carol will always fold the paper from left to right relative to the directed line given (see Figure-1). The cut is determined by the two points on the cut line. Please note that the points given to determine the fold or the cut are not necessarily on the paper.
Input
Output
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII; const double PI = acos(-1.0);
const double EPS = 1e-; inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
} struct Point {
double x, y;
Point() {}
Point(double x, double y): x(x), y(y) {}
void read() {
scanf("%lf%lf", &x, &y);
}
Point operator + (const Point &rhs) const {
return Point(x + rhs.x, y + rhs.y);
}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
Point operator * (double t) const {
return Point(x * t, y * t);
}
double length() const {
return sqrt(x * x + y * y);
}
Point unit() const {
double l = length();
return Point(x / l, y / l);
}
}; double dist(const Point &p1, const Point &p2) {
return (p1 - p2).length();
} Point rotate(const Point &p, double angle, const Point &o = Point(, )) {
Point t = p - o;
double x = t.x * cos(angle) - t.y * sin(angle);
double y = t.y * cos(angle) + t.x * sin(angle);
return Point(x, y) + o;
} double cross(const Point &a, const Point &b) {
return a.x * b.y - a.y * b.x;
} double cross(const Point &sp, const Point &ep, const Point &op) {
return cross(sp - op, ep - op);
} struct Seg {
Point st, ed;
Seg() {}
Seg(Point st, Point ed): st(st), ed(ed) {}
void read() {
st.read(); ed.read();
}
};
typedef Seg Line;
//return Ax + By + C =0 's A, B, C
void Coefficient(const Line &L, double &A, double &B, double &C) {
A = L.ed.y - L.st.y;
B = L.st.x - L.ed.x;
C = L.ed.x * L.st.y - L.st.x * L.ed.y;
}
//point of intersection
Point operator * (const Line &a, const Line &b) {
double A1, B1, C1;
double A2, B2, C2;
Coefficient(a, A1, B1, C1);
Coefficient(b, A2, B2, C2);
Point I;
I.x = - (B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1);
I.y = (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1);
return I;
} double Point_to_Line(const Point &p, const Line &L) {
return fabs(cross(p, L.st, L.ed)/dist(L.st, L.ed));
} Point reflection(const Point &p, const Line &l) {
Point t = rotate(l.ed - l.st, -PI / );
return p + t.unit() * ( * Point_to_Line(p, l));
} vector<Point> p_vec, p_buf; struct Poly {
vector<int> id;
void add(int i) {
id.push_back(i);
}
Point& operator [] (int i) const {
return p_vec[id[i]];
}
}; vector<Poly> pol_vec, pol_buf;
map<PII, int> edge_map; Point paper[] = {Point(, ), Point(, ), Point(, ), Point(, )}; void reflection(const Poly &pol, const Line &l) {
for(int i = ; i < int(pol.id.size()); ++i)
if(pol.id[i] < int(p_buf.size())) p_buf[pol.id[i]] = reflection(pol[i], l);
} int intersection(int id1, int id2, const Point &p1, const Point &p2) {
map<PII, int>::iterator it = edge_map.find(make_pair(id1, id2));
if(it == edge_map.end()) {
p_vec.push_back(Line(p_vec[id1], p_vec[id2]) * Line(p1, p2));
edge_map[make_pair(id1, id2)] = edge_map[make_pair(id1, id2)] = p_vec.size() - ;
return p_vec.size() - ;
} else return it->second;
} void fold(const Point &p1, const Point &p2, const Poly &pol) {
Poly res1, res2;
int last_s = sgn(cross(p1, pol[], p2));
for(int i = ; i < int(pol.id.size()); ++i) {
int now_s = sgn(cross(p1, pol[i], p2));
if(now_s == ) {
res1.add(pol.id[i]);
res2.add(pol.id[i]);
} else if(now_s < ) {
if(last_s > ) {
int k = intersection(pol.id[i - ], pol.id[i], p1, p2);
res1.add(k);
res2.add(k);
}
res1.add(pol.id[i]);
} else if(now_s > ) {
if(last_s < ) {
int k = intersection(pol.id[i - ], pol.id[i], p1, p2);
res1.add(k);
res2.add(k);
}
res2.add(pol.id[i]);
}
last_s = now_s;
}
if(res1.id.size() > ) {
res1.add(res1.id[]);
reflection(res1, Line(p1, p2));
reverse(res1.id.begin(), res1.id.end());
pol_buf.push_back(res1);
}
if(res2.id.size() > ) {
res2.add(res2.id[]);
pol_buf.push_back(res2);
}
} void fold(const Point &p1, const Point &p2) {
p_buf = p_vec;
edge_map.clear();
pol_buf.clear();
for(int i = ; i < int(pol_vec.size()); ++i)
fold(p1, p2, pol_vec[i]);
pol_vec = pol_buf;
for(int i = ; i < int(p_buf.size()); ++i)
p_vec[i] = p_buf[i];
} void dfs(vector<bool> &vis, int id, const Line &l) {
vis[id] = true;
Poly &pol = pol_vec[id];
for(int i = ; i < int(pol.id.size() - ); ++i) {
if(sgn(cross(l.ed, pol[i], l.st)) == && sgn(cross(l.ed, pol[i + ], l.st)) == ) continue;
int id1 = pol.id[i], id2 = pol.id[i + ];
for(int j = ; j < int(pol_vec.size()); ++j) {
if(vis[j]) continue;
for(int k = ; k < int(pol_vec[j].id.size() - ); ++k) {
if(pol_vec[j].id[k] == id1 && pol_vec[j].id[k + ] == id2) {
dfs(vis, j, l);
break;
}
}
}
}
} int cut(const Line &l) {
int ret = ;
vector<bool> vis(p_vec.size());
for(int i = ; i < int(pol_vec.size()); ++i) {
if(!vis[i]) {
dfs(vis, i, l);
++ret;
}
}
return ret;
} int main() {
int T;
scanf("%d", &T);
Poly init_pol;
for(int i = ; i <= ; ++i) init_pol.add(i & );
while(T--) {
int n;
scanf("%d", &n);
p_vec.clear();
pol_vec.clear();
for(int i = ; i < ; ++i) p_vec.push_back(paper[i]);
for(int i = ; i <= ; ++i) pol_vec.push_back(init_pol);
Point p1, p2;
for(int i = ; i <= n; ++i) {
p1.read(), p2.read();
fold(p1, p2);
}
printf("%d\n", cut(Line(p1, p2)));
}
}
POJ 1921 Paper Cut(计算几何の折纸问题)的更多相关文章
- 【BZOJ】1074: [SCOI2007]折纸origami
http://www.lydsy.com/JudgeOnline/problem.php?id=1074 题意:一开始有一个左上角是(0,100),右下角是(100,0)的纸片,现在可以沿有向直线折n ...
- 1074: [SCOI2007]折纸origami
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 372 Solved: 229[Submit][Status][Discuss] Descriptio ...
- 【题解】折纸 origami [SCOI2007] [P4468] [Bzoj1074]
[题解]折纸 origami [SCOI2007] [P4468] [Bzoj1074] 传送门:折纸 \(\text{origami [SCOI2007] [P4468]}\) \(\text{[B ...
- CSS3写折纸
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- 折纸问题java实现
/** * 折纸问题 这段代码写的太low了 本人水平有限 哎... 全是字符串了 * @param n * @return * @date 2016-10-7 * @author shaobn */ ...
- 1074: [SCOI2007]折纸origami - BZOJ
Description 桌上有一张边界平行于坐标轴的正方形纸片,左下角的坐标为(0,0),右上角的坐标为(100,100).接下来执行n条折纸命令.每条命令用两个不同点P1(x1,y1)和P2(x2, ...
- CSS3实现文字折纸效果
CSS3实现文字折纸效果 效果图: 代码如下,复制即可使用: <!DOCTYPE html> <html> <head> <title></tit ...
- UVA 177 PaperFolding 折纸痕 (分形,递归)
著名的折纸问题:给你一张很大的纸,对折以后再对折,再对折……每次对折都是从右往左折,因此在折了很多次以后,原先的大纸会变成一个窄窄的纸条.现在把这个纸条沿着折纸的痕迹打开,每次都只打开“一半”,即把每 ...
- ZR#955 折纸
ZR#955 折纸 解法: 可以发现折纸之后被折到上面的部分实际上是没有用的,因为他和下面对应位置一定是一样的,而影响答案的只有每个位置的颜色和最底层的坐标范围.因此,我们只需要考虑最底层即可,即我们 ...
随机推荐
- mysql主从延迟复制
需求描述 正常情况下我们是不会有刻意延迟从库的需求的,因为正常的线上业务自然是延迟越低越好.但是针对测试场景,业务上偶尔需要测试延迟场景下业务是否能正常运行. 解决方案 针对这种场景mysql有一个叫 ...
- 用sqldeveloper连接数据库
用sql developer连接sqlserver,连接窗口默认没有sqlsever页签,需要配置数据库驱动: 具体步骤: 1.工具--首选项--数据库--第三方JDBC驱动
- 原生JS实现移动端的轮播效果
首先 我们想实现的效果是在手指按下拖动的时候图片能够跟随移动(无动画效果)然后松开手指后判断图片移动的位置 和某一个值进行比较 在这里我们默认定为盒子的1/3宽度 当x轴的移动位置大于1/3的时候图片 ...
- 自添加LUCI菜单及编译为ipk
目录 添加汉化编译为ipk配置文件入口函数界面文件Makefile 添加 添加自己的luci界面,有3个必要的要素: a配置文件.新建一个在/etc/config/abcdefg b入口函数.新建一个 ...
- python学习第三天 -----2019年4月23日
第三周-第03章节-Python3.5-集合及其运算 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 ...
- 第二节 双向链表的GO语言实现
一.什么是双向链表 和单链表比较,双向链表的元素不但知道自己的下线,还知道自己的上线(越来越像传销组织了).小煤车开起来,图里面可以看出,每个车厢除了一个指向后面车厢的箭头外,还有一个指向前面车厢的箭 ...
- vs2013工程配置
1. 目标文件生成路径配置: 直接改在工程同级目录下 x64\debug目录下: 2. 调试工程路径配置: 命令-----参照物为工程 工作目录----参照物为运行程序 3. 拷贝工程: bat的写 ...
- 高斯消元c++(非常暴力)
暴力方法(已更新): #include<iostream> using namespace std; const int maxn = 1000; int n; double a[maxn ...
- 使用 Linux 下的的logrotate进行日志的切割
实际生产中,使用一个log文件来记录所有信息的话,一方面,时间过久,就会占用很大的空间:另一方面,就是一个文件记录对于后期日志的查看非常不利.为了解决查看了一下资料,发现linux里面有一个logro ...
- Java设计模式(14)——行为模式之不变模式(Immutable)
一.概述 概念 分类:弱不变模式(子类可变)和强不变模式(子类也是不可变) 应用场景 java.lang.String是一个经典的强不变类 二.分析 与享元模式的关系