2017-08-17 10 views
-2

eqは、すべての要素の形式がe =(F =(int、double)、S =(int、double))のイベントキューです。 イベントキューでイベントe =(F、S)を処理すると、set< pair<int, double> > elからe.Sを挿入または削除または挿入します。 e.Sを削除している間に、e.Sは既にelにあるとみなすことができます。私はel.erase(e.S)によってelからe.Sを削除しようとしていますC++のセットから消去中のセグメンテーションエラー

しかし、それはエラーを与える:

segmentation fault 11

助けてください。

#include <iostream> 
#include <vector> 
#include <cmath> 
#include <queue> 
#include <climits> 
#include <set> 

#define MP make_pair 
#define PB push_back 
#define F first 
#define S second 
#define OUT cout << 
#define IN cin >> 
#define newline cout << "\n" 
#define space cout << " " 
#define fastIO ios_base::sync_with_stdio(false); cin.tie(NULL); 
#define PI 3.14159265 
#define EPSILON 1e-9 
#define OBJ pair<int, double> 
#define EVENT pair< OBJ, OBJ > 

using namespace std; 

struct point { 
    int x, y; 
}; 

double angle(double x, double y) { 
    double t = atan2 (y, x) * 180.0/PI; 
    return t >= 0 ? t : 360 - fabs(t); 
} 

vector< struct point > vp; 

struct COMP { 
    bool operator()(const EVENT &p, const EVENT &q) { 
     if(fabs(p.F.S - q.F.S) > EPSILON) { 
      return p.F.S < q.F.S; 
     } 
     else if(p.F.F != q.F.F) return p.F.F == 0; 
     else return p.S.S < q.S.S; 
    } 
} comp_eq; 

vector<EVENT> eq; 

class comp_el { 
public: 
    bool operator()(const OBJ &p, const OBJ &q) { 
     if(fabs(p.S - q.S) > EPSILON) { 
      return p.S < q.S; 
     } 
     else { 
      double a_p = angle(vp[p.F].y, vp[p.F].x), a_q = angle(vp[q.F].y, vp[q.F].x); 
      if(fabs(a_p - a_q) > EPSILON) return a_p < a_q; 
      else return false; 
     } 
    } 
}; 

set< OBJ, comp_el > el; 

int main() { 
    int n, r; 
    double theta, phi, d, beg, end; 
    vector<struct point> vp; 
    struct point p; 
    while(1) { 
     IN n; 
     if(n == 0) break; 
     eq.clear(); 
     vp.clear(); 
     for(int j = 0; j < n; j++) { 
      IN p.x; 
      IN p.y; 
      IN r; 
      vp.PB(p); 
      d = sqrt(p.x * p.x + p.y * p.y); 
      theta = angle(p.y, p.x); 
      phi = asin(r/d); 
      beg = theta - phi; 
      beg = beg < 0 ? 360 - fabs(beg) : beg; 
      eq.PB(MP(MP(0, beg), MP(j, d))); 
      if(fabs(beg - 0) < EPSILON) { 
       eq.PB(MP(MP(0, 360), MP(j, d))); 
       eq.PB(MP(MP(1, 360), MP(j, d))); 
      } 
      end = beg + 2 * phi; 
      if(fabs(end - 360) > EPSILON) { 
       if(end > 360) { 
        eq.PB(MP(MP(1, 360), MP(j, d))); 
        eq.PB(MP(MP(0, 0), MP(j, d))); 
        eq.PB(MP(MP(1, end - 360), MP(j, d))); 
       } 
       else eq.PB(MP(MP(1, end), MP(j, d))); 
      } 
      else { 
       eq.PB(MP(MP(1, 360), MP(j, d))); 
       eq.PB(MP(MP(0, 0), MP(j, d))); 
       eq.PB(MP(MP(1, 0), MP(j, d))); 
      } 
     } 
     sort(eq.begin(), eq.end(), comp_eq); 


     //I NEED HELP IN THE PART BELOW. 


     for(int j = 0; j < eq.size(); j++) { 
      EVENT e = eq[j]; 
      OUT e.F.F; 
      space; 
      OUT e.F.S; 
      space; 
      OUT e.S.F; 
      space; 
      OUT e.S.S; 
      space; 
      newline; 
     } 
     double maxD = -INT_MAX; 
     for(int j = 0; j < eq.size(); j++) { 
      EVENT e = eq[j]; 
      if(e.F.F == 0) { 
       el.insert(e.S); 
      } 
      else { 
       el.erase(e.S); 
      } 
      set<OBJ>::iterator first = el.begin(); 
      // for(; first != el.end(); first++){ 
      // OUT (*first).F; space; OUT (*first).S; 
      // } 
      // newline; 
      if(first != el.end()) { 
       OUT (*first).F; 
       space; 
       OUT (*first).S; 
       newline; 
       if((*first).S > maxD) maxD = (*first).S; 
      } 
     } 
     OUT maxD; 
     newline; 
    } 
    return 0; 
} 
+2

なぜmake_pairをMPに、push_backをPBに定義するのですか?これは私の意見では本当に悪いスタイルです。それは実際にコードを速く書くのに役立つわけではありませんが、コードを読むのが100倍難しくなります。 push_back(make_pair(Foo))の組み合わせをemplace_back(Foo)に減らす必要があります。 –

+1

デバッガでコードを1行ずつ進めていくときに何を観察しましたか? – user0042

+0

'beg = theta-phi'はあまり意味がありません:' theta'は度ですが 'phi'はラジアンです。 –

答えて

0

comp_elグローバル変数vp内の要素を検索しようとする試み - しかし、そのベクトルは常に空です。 main()は代わりに、vpという名前のローカル変数に値を代入しますが、それ以外の場合はグローバルvpとは異なります。プログラムは、境界外のインデックスを持つベクトル要素にアクセスすることによって、未定義の動作を示します。 「十分近い」、ほぼ平等に基づいてコンパレータ(fabs(p.F.S - q.F.S) > EPSILON、のように)一般的に厳しい弱い順序付けの要件を満たしていないことを


も注意してください。そのようなコンパレータは、誘導同値関係は推移ではありません:三つの要素Aを見つけることが可能であるBABに十分に近く、BCに十分に近いですが、ACに十分に近接していないようC

関連する問題