BZOJ1074 [SCOI2007]折纸origami

我们先看每个点可能从哪些点折过来的,2^10枚举对角线是否用到。

然后再模拟折法,查看每个点是否满足要求。

恩,计算几何比较恶心,还好前几天刚写过一道更恶心的计算几何,点类直接拷过来2333。

  1 /**************************************************************
  2     Problem: 1074
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:24 ms
  7     Memory:980 kb
  8 ****************************************************************/
  9
 10 #include <cstdio>
 11 #include <cmath>
 12 #include <algorithm>
 13
 14 using namespace std;
 15 typedef double lf;
 16
 17 const int N = 10;
 18 const lf eps = 1e-8;
 19
 20 int n, cnt;
 21
 22 inline lf sqr(lf x) {
 23     return x * x;
 24 }
 25
 26 inline int dcmp(lf x) {
 27     return fabs(x) <= eps ? 0 : (x > eps ? 1 : -1);
 28 }
 29
 30 struct point {
 31     lf x, y;
 32     point() {}
 33     point(lf _x, lf _y) : x(_x), y(_y) {}
 34
 35     inline point operator + (point p) {
 36         return point(x + p.x, y + p.y);
 37     }
 38     inline point operator - (point p) {
 39         return point(x - p.x, y - p.y);
 40     }
 41     inline lf operator * (point p) {
 42         return x * p.y - y * p.x;
 43     }
 44     inline lf operator % (point p) {
 45         return x * p.x + y * p.y;
 46     }
 47     inline point operator * (lf a) {
 48         return point(x * a, y * a);
 49     }
 50     inline point operator / (lf a) {
 51         return point(x / a, y / a);
 52     }
 53
 54     inline bool operator < (const point &p) const {
 55         return dcmp(x - p.x) == 0 ? dcmp(y - p.y) < 0 : dcmp(x - p.x) < 0;
 56     }
 57     inline bool operator != (const point &p) const {
 58         return dcmp(x - p.x) || dcmp(y - p.y);
 59     }
 60     inline bool operator == (const point &p) const {
 61         return !dcmp(x - p.x) && !dcmp(y - p.y);
 62     }
 63
 64     inline void read_in() {
 65         scanf("%lf%lf", &x, &y);
 66     }
 67     friend inline lf dis2(point p) {
 68         return sqr(p.x) + sqr(p.y);
 69     }
 70     friend inline lf dis(point p) {
 71         return sqrt(dis2(p));
 72     }
 73     friend inline lf angle(point p, point q) {
 74         return acos(p % q / dis(p) / dis(q));
 75     }
 76     friend inline point rotate(point p, lf A) {
 77         lf s = sin(A), c = cos(A);
 78       return point(p.x * c - p.y * s, p.x * s + p.y * c);
 79     }
 80 } ans[N << 10];
 81
 82 struct line {
 83     point p, v;
 84     line() {}
 85     line(point _p, point _v) : p(_p), v(_v){}
 86 } l[N];
 87
 88 inline point reverse(point p, line l, int f) {
 89     return l.p + rotate(p - l.p, angle(p - l.p, l.v) * 2 * f);
 90 }
 91
 92 inline bool on_left(point p, line l) {
 93     return dcmp((p - l.p) * l.v) < 0;
 94 }
 95
 96 inline bool on_right(point p, line l) {
 97     return dcmp((p - l.p) * l.v) > 0;
 98 }
 99
100 void dfs(point p, int d) {
101     ans[++cnt] = p;
102     if (d == 0) return;
103     dfs(p, d - 1);
104     if (on_left(p, l[d])) dfs(reverse(p, l[d], -1), d - 1);
105 }
106
107 inline bool check(lf x) {
108     return dcmp(x) > 0 && dcmp(x - 100) < 0;
109 }
110
111 inline bool check(point p) {
112     return check(p.x) && check(p.y);
113 }
114
115 inline point find(point p) {
116     int i;
117     for (i = 1; i <= n; ++i)
118         if (on_right(p, l[i])) p = reverse(p, l[i], 1);
119         else if (!on_left(p, l[i])) return point(-1, -1);
120     return p;
121 }
122
123 int work(point p) {
124     int res = 0, i;
125     cnt = 0;
126     dfs(p, n);
127     sort(ans + 1, ans + cnt + 1);
128     cnt = unique(ans + 1, ans + cnt + 1) - ans - 1;
129     for (i = 1; i <= cnt; ++i)
130         if (check(ans[i]) && find(ans[i]) == p) ++res;
131     return res;
132 }
133
134 int main() {
135     int i, Q;
136     point x, y;
137     scanf("%d", &n);
138     for (i = 1; i <= n; ++i) {
139         x.read_in(), y.read_in();
140         l[i] = line(x, y - x);
141     }
142     scanf("%d", &Q);
143     while (Q--) {
144         x.read_in();
145         printf("%d\n", work(x));
146     }
147     return 0;
148 }

时间: 2024-12-20 14:36:22

BZOJ1074 [SCOI2007]折纸origami的相关文章

【BZOJ】1074: [SCOI2007]折纸origami

http://www.lydsy.com/JudgeOnline/problem.php?id=1074 题意:一开始有一个左上角是(0,100),右下角是(100,0)的纸片,现在可以沿有向直线折n次(n<=8,右边折向左边),折完后,有m个询问(m<=50),每次询问一个点在最终的图形中穿过了几次纸片. #include <cstdio> #include <cstring> #include <cmath> #include <string>

1074: [SCOI2007]折纸origami

Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 372  Solved: 229[Submit][Status][Discuss] Description 桌上有一张边界平行于坐标轴的正方形纸片,左下角的坐标为(0,0),右上角的坐标为(100,100).接下来执行n条折纸命令.每条命令用两个不同点P1(x1,y1)和P2(x2,y2)来表示,执行时把当前的折纸作品沿着P1P2所在直线折叠,并把有向线段P1P2的右边折向左边(左边的部分保持不变).

P4468 [SCOI2007]折纸

题意 似乎边界上(折线上.正方形纸片边上)的点认为是\(0\). 由于操作次数很少,因此逆着操作,求出所有可能的点,之后正向模拟一遍判断即可. 求一个点关于一个向量的对称点:用向量旋转求出方向向量即可. code: #include<bits/stdc++.h> using namespace std; const int maxn=10; const double eps=1e-8; const double Pi=acos(-1.0); const double inf=1e9; int

CSS3写折纸

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>折纸选项卡</title> <style> @-webkit-keyframes open { 0% { -webkit-transform:rotateX(-120deg);

关于折纸的动画

其实关于折纸的重点是在HTML和CSS的布局上主要就是要一个嵌套一个,如果不是的话,会有撑开的宽高从而难以连接在一起.不过折纸还没有写完一些兼容,也是参考视频上作的小练习 <html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题</title></head><bo

折纸问题java实现

1 /** 2 * 折纸问题 这段代码写的太low了 本人水平有限 哎... 全是字符串了 3 * @param n 4 * @return 5 * @date 2016-10-7 6 * @author shaobn 7 */ 8 public static String[] flodpaper(int n){ 9 int length = (int)Math.pow(2,n)-1; 10 int position = (int)Math.pow(2,n-1)-1; 11 String[] s

例题1折纸痕

递归算法的思路,使用 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; namespace 例题1折纸痕 {     

UVA 177 PaperFolding 折纸痕

著名的折纸问题:给你一张很大的纸,对折以后再对折,再对折……每次对折都是从右往左折,因此在折了很多次以后,原先的大纸会变成一个窄窄的纸条.现在把这个纸条沿着折纸的痕迹打开,每次都只打开“一半”,即把每个痕迹做成一个直角,那么从纸的一端沿着和纸面平行的方向看过去,会看到一条美妙的曲线. 就是一个分形,规定一下,纸的朝向,然后不难发现规律.图形输出方面,存下x和y坐标,然后下标排个序,或者用map. 为什么感觉模拟好难写啊... //Rey 2015.8.3 #include<bits/stdc++

[FZYZOJ 2162] Zrn神犇之折纸游戏

P2162 -- Zrn神犇之折纸游戏 时间限制:2000MS 内存限制:524288KB Description Zrn神犇最近喜欢上一款折纸游戏,因此他几乎每天都拿着一条悠长悠长又寂寥的纸带折来折去.其具体规则是这样的: 这是一个长度为N,宽度为1的纸条,从1开始写着连续的N个自然数. 1 2 3 4 5 6 … N 如果它的长度为偶数,Zrn神犇则会很高兴,直接把它从左往右或从右往左对折.比如长度为6的纸条从左往右对折完就会是这样: 如果它的长度为质数,Zrn神犇则会觉得不太爽,他就只能把