UVa 1595 - Symmetry - 对称轴

https://vjudge.net/problem/UVA-1595

之前没做过这种题目,一时间没想出来如何下手。

想通之后,剩下的操作只剩下排序了。

对于任意n个散点,一旦给出,他们的对称轴实际上已经确定了,而且十分好求:

横对称轴 一定是 横坐标最大的X1和横坐标最小的 X2 的平均数,即 X= 1/2(X1 + X2

这个结论可以用反证法推出,画图十分好理解,证明就不赘述了。

下面问题是:找出了对称轴,如何将所有的点对应出来?

很自然的考虑到将所有的点按照与对称轴的位置关系分类:

< 1 >  如果这个点恰好在对称轴上,那么它一定对称(和自己对称),可以直接丢掉了。

< 2 > 如果在轴的左右两边:分别存在两个数组中,以后方便对应检验。

 

这个操作用for循环遍历很好实现。注意对称轴有可能是浮点数,因此要用double来表示。如果用int会误判

 

好了,现在已经将所有的点按两侧分开了,还需要解决什么呢?

两个数组的size是否相等? 这是最基本的一个条件,如果左右两边的点数都不同,那必然不对称,不需要进一步检验了,直接continue就好了(不是break...我一开始错在这里...)

 

如果size相同继续往后走:

还有两个要素:

< 1 > 离对称轴的距离多远?

< 2 > 高度 y 有多大?

 

处理这两个要素,其实很简单: 设计一个comp函数,进行多级排序即可。然后用两个迭代器同步遍历数组检查即可。

应该讲的比较清楚了。代码中就不写注释了。

AC代码:  10 ms

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <cmath>
 5 #define INF 0x3fffffff
 6 using namespace std;
 7 struct node{
 8     int x;
 9     int y;
10     double diff;
11 };
12 double SymmetricX;
13 bool Equal(double m,double n){
14     return fabs(m-n)<1e-6;
15 }
16 bool comp(const node&a,const node&b){
17     if(not Equal(a.diff,b.diff))return a.diff < b.diff;
18     else return a.y < b.y;
19 }
20 int main(){
21     int tests;
22     cin >> tests;
23     while(tests--){
24         int num;
25         cin >> num;
26         vector<node> arr(1001);
27         int find_max = -INF,max_point = -1;
28         int find_min =  INF,min_point = -1;
29         for(int i = 0; i < num; i++){
30             cin >> arr[i].x >> arr[i].y;
31             if(arr[i].x < find_min){
32                 find_min = arr[i].x;
33                 min_point = i;
34             }
35             if(arr[i].x > find_max){
36                 find_max = arr[i].x;
37                 max_point = i;
38             }
39         }
40         SymmetricX = (find_max + find_min)*1.0/2;
41         vector<node> lr[2];
42         for(int i = 0; i < num; i++){
43             double diff = arr[i].x - SymmetricX;
44             if(Equal(diff,0))continue;
45             arr[i].diff = fabs(diff);
46             if(diff  < 0)lr[0].push_back(arr[i]);
47             else lr[1].push_back(arr[i]);
48         }
49         if(lr[0].size() not_eq lr[1].size()){
50             cout<<"NO"<<endl;
51             continue;
52         }
53         sort(lr[0].begin(), lr[0].end(), comp);
54         sort(lr[1].begin(), lr[1].end(), comp);
55         vector<node> :: iterator it = lr[0].begin();
56         vector<node> :: iterator it2 = lr[1].begin();
57         int flag = 0;
58         while(it not_eq lr[0].end() and it2 not_eq lr[1].end()){
59             if(it->y not_eq it2->y){
60                 flag = 1;
61                 break;
62             }
63             it++; it2++;
64         }
65         if(flag)cout<<"NO"<<endl;
66         else cout<<"YES"<<endl;
67     }
68     return 0;
69 }
posted @ 2020-01-02 09:32  popozyl  阅读(261)  评论(0编辑  收藏  举报