hdu 1925 A Foldy but a Goody---点的旋转
Posted fzl194
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 1925 A Foldy but a Goody---点的旋转相关的知识,希望对你有一定的参考价值。
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1925
题目大意:
假设有一条很长的线,对它进行n次对折(n <= 30),给出每次对折的方向---向上对折或者向下对折。这样吧这根线分成m小段,m = 2^n,将这条线展开,对应的每个折痕做一个90度的角,把起始点作为第0号点,坐标为(0, 0),第一个拐角坐标为(1,0),求第k个点的坐标。
解题思路:
先动手折起来。
第一次对折,设折叠点为P1,把这条线分成两部分,接下来的n-1次操作,对这两部分的操作完全一样,所以这条线展开的时候,前一半和后一半的形状是完全一样的,只是后一半是前一半绕P1点顺时针(或者逆时针)90度而来的。这样,已知起始点的坐标为(0, 0)如果知道P1的坐标,那么可以直接求出最后一点的坐标。要求出P1的坐标,可以同理继续下去,P1是起始点绕P2顺时针或逆时针转90度得来的......而我们知道第n次折叠的点Pn = (1, 0)因此可以迅速求处所有折叠点的坐标。
接着对于第k个转折点的坐标也可以用类似的方法,观察一下,比如4步操作LLUL后,有16个点,求第13个点,就是第3个点绕第8个点旋转而来,至于顺时针还是逆时针,由于绕的是第8个点旋转而来,为2的三次方,总共是2的4次方,所以应该是第一次的操作,因为第一次操作时,将前半部分和后半部分重叠,此时3和13正好重叠。
点旋转公式
x1,y1绕点x0,y0逆时针旋转a度
x2 = (x1 - x0)cos(a) - (y1 - y0)sin(a) + x0
y2 = (x1 - x0)sin(a) + (y1 - y0)cos(a) + y0
所以顺时针旋转90度等价于逆时针旋转-90度
向下对应着逆时针 向上对应顺时针(折纸得出的规律)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 struct node 5 { 6 int x, y; 7 node(){} 8 node(int x, int y):x(x), y(y){} 9 }; 10 node shun(node a, node b)//a点绕b点顺时针90度 11 { 12 node c; 13 c.x = b.x - b.y + a.y; 14 c.y = b.y + b.x - a.x; 15 return c; 16 } 17 node ni(node a, node b)//a点绕b点逆时针90度 18 { 19 node c; 20 c.x = b.x + b.y - a.y; 21 c.y = b.y - b.x + a.x; 22 return c; 23 } 24 map<int, node>Flip; 25 string s; 26 int n, k; 27 node dfs(int x) 28 { 29 //cout<<x<<endl; 30 if(Flip.count(x))return Flip[x]; 31 int t = 1, tmp, cnt = 0; 32 while(t <= x)t *= 2, cnt++; 33 tmp = t - x; 34 if(s[n - cnt] == ‘L‘) 35 return Flip[x] = ni(dfs(tmp), Flip[1 << (cnt - 1)]); 36 else 37 return Flip[x] = shun(dfs(tmp), Flip[1 << (cnt - 1)]); 38 } 39 int main() 40 { 41 int T; 42 cin >> T; 43 while(T--) 44 { 45 Flip.clear(); 46 cin >> s >> k; 47 n = s.size(); 48 Flip[1] = node(1, 0); 49 node tmp(0, 0); 50 Flip[0] = node(0, 0); 51 for(int i = 1; i <= n; i++) 52 { 53 if(s[n - i] == ‘L‘)//向下为逆时针 54 Flip[(1<<i)] = ni(tmp, Flip[1<<(i - 1)]); 55 else 56 Flip[(1<<i)] = shun(tmp, Flip[1<<(i - 1)]); 57 //cout<<Flip[1<<i].x<<" "<<Flip[1<<i].y<<endl; 58 } 59 dfs(k); 60 cout<<"("<<Flip[k].x<<","<<Flip[k].y<<") "; 61 } 62 return 0; 63 }
以上是关于hdu 1925 A Foldy but a Goody---点的旋转的主要内容,如果未能解决你的问题,请参考以下文章
hdu6601 Keen On Everything But Triangle 主席树+斐波那契数列妙用