STL之map、set灵活使用

1、LA 5908/UVA1517 Tracking RFIDs

  题意:给出s个传感器的位置,以及其感应范围。如果某个方向上有墙,则该方向上感应距离减1.现在有w个墙,给出p个物品的位置,问其能被几个传感器探测到。

  思路:传感器用set保存。之后传感器和物品之间是否有墙用线段是否相交来判断。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<vector>
  4 #include<set>
  5 #include<cmath>
  6 using namespace std;
  7 typedef long long ll;
  8 const double eps = 1e-6;
  9 
 10 struct point
 11 {
 12     int x, y;
 13     point(int xx=0, int yy=0):x(xx),y(yy){ }
 14     friend bool operator < (const point& a,const point& b)
 15     {
 16         return (a.x != b.x) ? a.x < b.x : a.y < b.y;
 17     }
 18 };
 19 struct line
 20 {
 21     int x;
 22     int y;
 23     line(int xx=0,int yy=0):x(xx),y(yy){ }
 24 };
 25 
 26 line operator - (point a, point b)
 27 {//得到点a和点b形成的直线的方向向量
 28     return line(a.x - b.x, a.y - b.y);
 29 }
 30 int cross(line a, line b)
 31 {//返回0则两条直线平行,否则,直线相交:大于0说明b.y/b.x>a.y/a.x,b的斜率大
 32     return a.x * b.y - b.x * a.y;
 33 }
 34 double dis(point a, point b)
 35 {//两点之间的直线距离
 36     return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
 37 }
 38 
 39 int direction(point p1, point p2, point p3)
 40 {//判断点p3在直线p1-p2上还是在其两侧,上侧为负,下侧为正,在直线上为0
 41     return cross(p3 - p1, p2 - p1);
 42 }
 43 
 44 //判断点np是否在线段p1-p2
 45 bool on_segment(point p1, point p2, point np)
 46 {
 47     if (np.x < min(p1.x, p2.x)) return false;
 48     if (np.x > max(p1.x, p2.x)) return false;
 49     if (np.y < min(p1.y, p2.y)) return false;
 50     if (np.y > max(p1.y, p2.y)) return false;
 51     return true;
 52 }
 53 
 54 //判断线段p1-p2和p3-p4是否相交
 55 bool segment_intersect(point p1, point p2, point p3, point p4)
 56 {
 57     // 必须用 long long
 58     ll d1 = direction(p1, p2, p3);
 59     ll d2 = direction(p1, p2, p4);
 60     ll d3 = direction(p3, p4, p1);
 61     ll d4 = direction(p3, p4, p2);
 62 
 63     if (d1 * d2 < 0 && d3 * d4 < 0) return true;//p1、p2分别在线段p3-p4两侧,并且p3、p4分别在线段p1-p2两侧则说明两条线段相交
 64     if (d1 == 0 && on_segment(p1, p2, p3)) return true;
 65     if (d2 == 0 && on_segment(p1, p2, p4)) return true;
 66     if (d3 == 0 && on_segment(p3, p4, p1)) return true;
 67     if (d4 == 0 && on_segment(p3, p4, p2)) return true;
 68     return false;
 69 }
 70 
 71 set<int> sensors[20005];//传感器坐标
 72 set<int>::iterator it;
 73 point wall_l[15], wall_r[15];//墙的起止点坐标
 74 
 75 int main()
 76 {
 77     int T;
 78     scanf("%d", &T);
 79 
 80     while (T--)
 81     {
 82         for (int i = 0; i < 20005; i++)
 83             sensors[i].clear();
 84 
 85         int s, r, w, p;
 86         scanf("%d%d%d%d", &s, &r, &w, &p);
 87 
 88         for (int i = 0; i < s; i++)
 89         {
 90             int x, y;
 91             scanf("%d%d", &x, &y);
 92             sensors[x + 10000].insert(y);//注意x为负数处理
 93         }
 94 
 95         for (int i = 0; i < w; i++)
 96             scanf("%d%d%d%d", &wall_l[i].x, &wall_l[i].y, &wall_r[i].x, &wall_r[i].y);
 97 
 98         while (p--)
 99         {
100             point p1;
101             scanf("%d%d", &p1.x, &p1.y);
102 
103             vector<point> ans;
104             for (int i = -r; i <= r; i++)
105             {//枚举x差值
106                 int x = p1.x + i;
107                 int y = ceil(p1.y - sqrt(r*r - (p1.x - x)*(p1.x - x)));//确定当前x坐标y可取下限
108                 int k = x + 10000;
109                 if (k < 0 || k > 20000) continue;
110                 it = sensors[k].lower_bound(y);
111                 while (it != sensors[k].end())
112                 {//传感器的横坐标为x,从当前y值增加
113                     point p2(x, *it++);//当前可取传感器
114                     double d = dis(p1, p2);
115                     if (d > r + eps) break;
116 
117                     double add = 0;
118                     for (int k = 0; k < w; k++)//判断是否有墙在两点之间
119                         if (segment_intersect(p1, p2, wall_l[k], wall_r[k])) add++;
120 
121                     if (d + add < r + eps) ans.push_back(p2);
122                 }
123             }
124             sort(ans.begin(), ans.end());
125             printf("%d", ans.size());
126             for (int i = 0; i < ans.size(); i++)
127                 printf(" (%d,%d)", ans[i].x, ans[i].y);
128             printf("\n");
129         }
130     }
131     return 0;
132 }
View Code

 2、 LA 3634/UVA 12096 The SetStack Computer

  题意:模拟集合栈。

  思路:给每一个不同集合映射一个编号。

 1 #include <iostream>
 2 #include <set>
 3 #include <map>
 4 #include <vector>
 5 #include <stack>
 6 #include <algorithm>
 7 #include<iterator>
 8 using namespace std;
 9 
10 map<set<int>, int> id;
11 map<set<int>, int>::iterator it;
12 vector<set<int> > v;
13 char op[15];
14 int getID(set<int> x)
15 {
16     it = id.find(x);
17     if (it != id.end())
18         return it->second;
19     v.push_back(x);
20     return id[x] = v.size() - 1;
21 }
22 
23 int main()
24 {
25     int T, n;
26     scanf("%d", &T);
27     while (T--)
28     {
29         scanf("%d", &n);
30         id.clear();
31         v.clear();
32         stack<int> s;
33         while (n--)
34         {
35             scanf("%s", op);
36             if (op[0] == 'P')
37                 s.push(getID(set<int>()));
38             else if (op[0] == 'D')
39                 s.push(s.top());
40             else
41             {
42                 set<int> t1 = v[s.top()]; s.pop();
43                 set<int> t2 = v[s.top()]; s.pop();
44                 set<int> t;
45                 if (op[0] == 'U')
46                 {
47                     set_union(t1.begin(), t1.end(), t2.begin(), t2.end(), inserter(t, t.begin()));
48                     s.push(getID(t));
49                 }
50                 else if (op[0] == 'I')
51                 {
52                     set_intersection(t1.begin(), t1.end(), t2.begin(), t2.end(), inserter(t, t.begin()));
53                     s.push(getID(t));
54                 }
55                 else if (op[0] == 'A')
56                 {
57                     t2.insert(getID(t1));
58                     s.push(getID(t2));
59                 }
60             }
61             printf("%d\n",v[s.top()].size());
62         }
63         printf("***\n");
64     }
65     return 0;
66 }
View Code

 

posted @ 2017-08-29 14:50  萌萌的美男子  阅读(295)  评论(0编辑  收藏  举报