zoukankan      html  css  js  c++  java
  • UVa 1595

    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 }
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    跳跃游戏1,2
    重叠子区间问题
    最长公共子序列问题
    由leetcode俄罗斯套娃信封问题到C++的sort()函数学习
    一道笔试题,做的很垃圾
    Spring boot框架快速入门
    Redis常用数据类型及其对应的底层数据结构
    Java 类加载机制及双亲委派模型
    Java面试高频知识点总结 part3
    Spring框架专题
  • 原文地址:https://www.cnblogs.com/popodynasty/p/12131542.html
Copyright © 2011-2022 走看看