标签:pen length 使用 soft mit collision unp san ota
题目链接:http://poj.org/problem?id=2991
挑战程序设计竞赛书上的例题。书上的思路还是蛮巧妙的,第一遍看真的没怎么看太懂,今天算是终于弄懂了。
稍微思考即可想到如果都用向量表示的话实际上就是从s+1到n的区间更新了,每个向量都旋转一定角度最后终点坐标实际上是全部向量的和。因此可以使用线段树进行区间更新。
书上更新的时候实际上是----对于包含了s的区间更新坐标,不包含s的区间只设置一个标志表示这一段区间已经旋转过了一定角度,每次需要更新的时候直接用这个角度计算即可。
另一方面就是旋转后坐标计算公式,没啥难度。。。。
代码:
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <queue> 5 #include <stack> 6 #include <cstdio> 7 #include <string> 8 #include <vector> 9 #include <cstdlib> 10 #include <cstring> 11 #include <sstream> 12 #include <iostream> 13 #include <algorithm> 14 #include <functional> 15 using namespace std; 16 #define rep(i,a,n) for (int i=a;i<n;i++) 17 #define per(i,a,n) for (int i=n-1;i>=a;i--) 18 #define all(x) (x).begin(),(x).end() 19 #define pb push_back 20 #define mp make_pair 21 #define lson l,m,rt<<1 22 #define rson m+1,r,rt<<1|1 23 typedef long long ll; 24 typedef vector<int> VI; 25 typedef pair<int, int> PII; 26 const ll MOD = 1e9 + 7; 27 const int inf = 0x3f3f3f3f; 28 #define M_PI 3.14159265358979323846 29 //head 30 #define maxn 70000 31 struct node{ 32 int left, right; 33 double vx, vy; 34 double angle; 35 node() {} 36 node(int l, int r, double x, double y, double ang): left(l), right(r), vx(x), vy(y), angle(ang){} 37 }; 38 node tree[maxn]; 39 double prv[maxn]; 40 int n, c; 41 int len[maxn]; 42 43 void build(int l, int r, int root){ 44 tree[root] = node(l, r, 0, 0, 0); 45 if(l == r){ 46 tree[root].vy = len[l]; 47 return; 48 } 49 int mid = (l + r) / 2; 50 build(l, mid, root << 1); 51 build(mid + 1, r, root << 1 | 1); 52 tree[root].vy = tree[root << 1].vy + tree[root << 1 | 1].vy; 53 return; 54 } 55 //rotate seg s+1 but won‘t change the coordinate of them 56 void update(int s, double a, int l, int r, int k){ 57 if(s < l) 58 return; 59 if(s == r && l == r) 60 return; 61 else if(s <= r){ 62 int lc = k << 1, rc = k << 1 | 1; 63 int mid = (l + r) / 2; 64 update(s, a, l, mid, lc); 65 update(s, a, mid + 1, r, rc); 66 67 if(s <= mid) 68 tree[k].angle += a; 69 double tmang = tree[k].angle; 70 tree[k].vx = tree[lc].vx + (cos(tmang) * tree[rc].vx - sin(tmang) * tree[rc].vy); 71 tree[k].vy = tree[lc].vy + (sin(tmang) * tree[rc].vx + cos(tmang) * tree[rc].vy); 72 } 73 } 74 75 int main(){ 76 while(scanf("%d %d", &n, &c) != EOF){ 77 memset(len, 0, sizeof(len)); 78 memset(tree, 0, sizeof(tree)); 79 for(int i = 0; i < n; i++) 80 prv[i] = M_PI; 81 for(int i = 0; i < n; i++) 82 scanf("%d", &len[i]); 83 build(0, n - 1, 1); 84 85 while(c--){ 86 int s, a; 87 scanf("%d %d", &s, &a); 88 s--; 89 double tma = a / 180.0 * M_PI; 90 update(s, tma - prv[s] , 0, n - 1, 1); 91 prv[s] = tma; 92 97 printf("%.2f %.2f\n", ansx, ansy); 98 } 99 puts(""); 100 } 101 }
题目:
Time Limit: 2000MS | Memory Limit: 65536K | |||
Total Submissions: 6807 | Accepted: 1822 | Special Judge |
Description
Input
Output
Sample Input
2 1 10 5 1 90 3 2 5 5 5 1 270 2 90
Sample Output
5.00 10.00 -10.00 5.00 -5.00 10.00
标签:pen length 使用 soft mit collision unp san ota
原文地址:http://www.cnblogs.com/bolderic/p/7144840.html