Problem p00689 (C++) — buggy submission, verdict: Runtime Error

/*
#include<algorithm>
#include<cassert>
#include<cmath>
#include<cstdio>
#include<iomanip>
#include<iostream>
#include<map>
#include<set>
#include<sstream>
#include<vector>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define F first
#define S second
#define all(n) (n).begin(),(n).end()
#define EPS (1e-8)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
using namespace std;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
struct Point
{
  double x,y;
  int index;
  Point(double x=-inf,double y=-inf):x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double p){return Point(x*p,y*p);}

  bool operator < (const Point& p)const
  {
    return !equals(x,p.x)?x < p.x:y > p.y;
  }
  bool operator == (const Point &p)const
  {
    return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
  }
};

struct Segment
{
  Point p1,p2;
  Segment(Point p1=Point(-inf,-inf),Point p2=Point(-inf,-inf)):p1(p1),p2(p2){}
};

typedef vector<Point> Polygon;
typedef Segment Line;
typedef vector<Point> Polygon;

double dot(Point a,Point b)
{
  return a.x*b.x+a.y*b.y;
}

double cross(Point a,Point b)
{
  return a.x*b.y-a.y*b.x;
}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

double toRad(double agl)
{
  return agl*M_PI/180.0;
}

int ccw(Point p0,Point p1,Point p2)
{
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) <-EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS) return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}


bool PointEquals(Point a,Point b)
{
  return equals(a.x,b.x) && equals(a.y,b.y);
}

double abs(Point a)
{
  return sqrt(norm(a));
}

double getDistanceLP(Line s,Point p)
{
  return abs(cross(s.p2-s.p1,p-s.p1))/abs(s.p2-s.p1);
}

double getDistanceSP(Segment s,Point p)
{
  if(dot(s.p2-s.p1,p-s.p1) < 0.0)return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2) < 0.0)return abs(p-s.p2);
  return getDistanceLP(s,p);
}

Polygon andrewScan(Polygon s,Point now)
{
  Polygon u,l;
  if(s.size() < 3)return s;
  sort(all(s));

  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);

  REP(i,2,s.size())
    {
      for(int n=u.size();n>=2 && ccw(u[n-2],u[n-1],s[i]) != CLOCKWISE;n--)
    {
      u.pop_back();
    }
      u.push_back(s[i]);
    }

  for(int i=s.size()-3;i>=0;i--)
    {
      for(int n=l.size();n>=2 && ccw(l[n-2],l[n-1],s[i]) != CLOCKWISE;n--)
    {
      l.pop_back();
    }
      l.push_back(s[i]);
    }

  reverse(l.begin(),l.end());
  for(int i=u.size()-2;i>=1;i--)l.push_back(u[i]);
  reverse(l.begin(),l.end());


  vector<Point> ret;

  bool f = false;
  rep(i,l.size())
    {
      if(l[i].index == now.index)f = true;
      if(f == false)continue;
      ret.push_back(l[i]);
      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index ==
l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) ==
ON_SEGMENT)ret.push_back(s[j]);
    }
    }

  rep(i,l.size())
    {
      if(l[i].index == now.index)f = false;
      if(f == false)break;
      ret.push_back(l[i]);

      rep(j,s.size())
    {
      if(s[j].index == l[i].index || s[j].index ==
l[(i+1)%l.size()].index)continue;
      if(getDistanceSP(Segment(l[i],l[(i+1)%l.size()]),s[j]) ==
ON_SEGMENT)ret.push_back(s[j]);
    }

    }


  return ret;
}

vector<Point> convex_hull(vector<Point> ps) {
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  vector<Point> ch(2*n);
  for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
    while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
    while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  ch.resize(k-1);
  return ch;
}


int n;
vector<Point> input;

void inputt()
{
  input.clear();
  input.resize(n);
  rep(i,n)
    {
      cin >> input[i].x >> input[i].y;
      input[i].index = i;
    }
}

void solve()
{
  bool used[n];
  rep(i,n)used[i] = false;
  double L = 0;
  Point cur = Point(0,0);
  cur.index = -1;

  rep(_,n)
    {
      vector<Point> toConvex;
      rep(i,n)
        {
          if(used[i])continue;
          toConvex.push_back(input[i]);
        }
      toConvex.push_back(cur);

      toConvex = convex_hull(toConvex);
      reverse(toConvex.begin(),toConvex.end());

      vector<Point> tmp;
      rep(j,toConvex.size())
        {
          tmp.push_back(toConvex[j]);
          rep(i,n)
            {
              if(used[i])continue;
              if(toConvex[j].index == input[i].index ||
toConvex[(j+1)%toConvex.size()].index == input[i].index)continue;
              if(equals(getDistanceSP(Segment(toConvex[j],toConvex[(j+1)%toConvex.size()]),input[i]),0))
                {
                  tmp.push_back(input[i]);
                }
            }
        }
      toConvex = tmp;


      cout << "toConvex----- cur : " << cur.x << "," << cur.y << endl;
      rep(i,toConvex.size())
      {
          cout << toConvex[i].x << "," << toConvex[i].y  << " " <<
toConvex[i].index<< endl;
        }
      cout << endl;


      int next = -inf;
      rep(i,toConvex.size())
        {
          if(toConvex[i].index == cur.index)
            {
              next = toConvex[(i+1)%toConvex.size()].index;
              break;
            }
        }

      assert(next != -inf);
      cout << "next = " << next << " : " << input[next].x << "," <<
input[next].y << endl; used[next] = true; L += sqrt(norm(cur-input[next])); cur
= input[next];

    }

  L *= 10.0;
  L = round(L);
  L /= 10.0;
  cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
}

int main()
{
  while(cin >> n,n)
    {
      inputt();

      solve();

    }
  return 0;
}

//変数に一旦いれてたらばぐった

*/

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 28)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define all(n) (n).begin(), (n).end()
#define pow2(a) (a) * (a)
using namespace std;
double EPS = 1e-9;

bool equals(double a, double b) { return fabs((a) - (b)) < EPS; }

class Point {
public:
  int x, y;

  Point(int x = -1, int y = -1) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(int a) { return Point(a * x, a * y); }
  Point operator/(int a) { return Point(x / a, y / a); } // ※イケメンに限る

  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }
};

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(-1, -1), Point p2 = Point(-1, -1))
      : p1(p1), p2(p2) {}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }

double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double norm(Point a) { return a.x * a.x + a.y * a.y; }

double getArgV2(Point A, Point B) {
  return acos(dot(A, B) / (sqrt(norm(A)) * sqrt(norm(B))));
  double a = sqrt(norm(A));
  double b = sqrt(norm(B));
  return acos(dot(A, B) / (a * b));
}

bool cmp(const Point &a, const Point &b) {
  if (a.x != b.x)
    return a.x < b.x;
  return a.y < b.y;
}

Point ps[1000];
bool used[1000];

int main() {

  int n;
  while (cin >> n, n) {
    rep(i, n) cin >> ps[i].x >> ps[i].y;
    Point cur(0, 0);
    Point cur2(0, -512);
    double L = 0;
    int last = n;

    rep(_, n) {
      /*
      cout << "remain"<<endl;
      rep(i,last)
        {
          cout << ps[i].x << "," << ps[i].y << endl;
        }
      cout << endl;
      */
      int next = 0;
      REP(i, 1, last) {
        if (equals(atan2(ps[next].y - cur.y, ps[next].x - cur.x),
                   atan2(ps[i].y - cur.y, ps[i].x - cur.x))) {
          if (pow2(cur.x - ps[next].x) + pow2(cur.y - ps[next].y) >
              pow2(cur.x - ps[i].x) + pow2(cur.y - ps[i].y)) {
            next = i;
          }
        } else if (getArgV2(cur - cur2, ps[next] - cur) >
                   getArgV2(cur - cur2, ps[i] - cur)) {
          next = i;
        }
      }
      // cout << "erase : " << ps[next].x << "," << ps[next].y << endl;
      L += sqrt(pow2(cur.x - ps[next].x) + pow2(cur.y - ps[next].y));
      cur2 = cur;
      cur = ps[next];
      ps[next] = ps[last - 1];
      last--;
    }

    printf("%.1f\\n", L);
  }
  return 0;
}

/*
int main()
{
  Point A = Point(0,10);
  Point B = Point(-10,15);

  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;
  B = Point(11,20);
  cout << atan2(B.y-A.y,B.x-A.x)*180/M_PI << endl;


  int n;
  while(cin >> n,n)
    {


      Point cur1 = Point(0,0);
      Point cur2 = Point(0,0);

      rep(i,n)
        {
          cin >> ps[i].x >> ps[i].y;
          cout << i << " :: " << ps[i].x << "," << ps[i].y << endl;
          used[i] = false;
        }
      cout << atan2(ps[5].y-ps[4].y,ps[5].x-ps[4].x)*180/M_PI << endl;
      cout << "##### " << getArgV2(ps[5]-ps[4],ps[4]-Point(0,0))*180/M_PI <<
endl; sort(ps,ps+n,cmp);



      bool f = true;
      double L = 0;
      rep(_,n)
        {
          if(_ == 0)
            {
              L += sqrt(norm(ps[0]-cur1));
              cur1 = ps[0];
              used[0] = true;
              //cout << "L = " << L << endl;
              continue;
            }
          double minArg = inf;
          double minDist = inf;
          int minpos = -inf;
          rep(i,n)
            {
              if(used[i])continue;

              //cout << "cur1(" << cur1.x << "," << cur1.y << ")" << endl;
              //cout << "cur2(" << cur2.x << "," << cur2.y << ")" << endl;
              //cout << "ps["<<i<<"](" << ps[i].x << "," << ps[i].y << ")" <<
endl;

              double arg = getArgV2(cur1-cur2,ps[i]-cur1);

              if(f)
                {
                  f = false;
                  minpos = i;
                  minArg = arg;
                  continue;
                }

              //cout << arg << " ::: " << endl;
              if(!equals(arg,minArg) && arg < minArg)
                {
                  minpos = i;
                  minArg = arg;
                  minDist = sqrt(norm(cur1-ps[i]));
                }
              if(equals(arg,minArg) && sqrt(norm(cur1-ps[minpos])) >
sqrt(norm(cur1-ps[i])))
                {
                  minDist = sqrt(norm(cur1-ps[i]));
                  minpos = i;

                }

            }
          //cout << "cur1 (" << cur1.x << "," << cur1.y << ")" << endl;
          //cout << "phase #" << _ << " " << minpos << "(" << ps[minpos].x <<
"," << ps[minpos].y << ")" << endl;
          //cout << "that arg is " << minArg*180/M_PI << endl;

          //assert(minpos != -inf);
          used[minpos] = true;
          L += sqrt(norm(cur1-ps[minpos]));
          cur2 = cur1;
          cur1 = ps[minpos];

          //cout << "L = " << L << endl << endl;
        }
      //L *= 10.0;
      //L = round(L);
      //L /= 10.0;
      //cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
      printf("%.1f\\n",L);
    }
  return 0;
}
*/
/*
#include<algorithm>
#include<cassert>
#include<cmath>
#include<cstdio>
#include<iomanip>
#include<iostream>
#include<vector>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define all(n) (n).begin(),(n).end()

using namespace std;
double EPS = 1e-9;

bool equals(double a,double b)
{
  return fabs((a)-(b)) < EPS;
}

struct Point
{
  double x,y;
  Point(double x=-inf,double y=-inf):x(x),y(y){}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  bool operator < (const Point &b)const
  {
    if(x != b.x)return x < b.x;
    return y < b.y;
  }
};

Point ps[410];
bool use[410];

double toRad(double agl){ return agl*M_PI/180; }

double getArg(Point a,Point bb)
{

}

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

int main()
{
  int n;
  while(cin >> n,n)
    {
      rep(i,n)
        {
          cin >> ps[i].x >> ps[i].y;
          use[i] = false;
        }
      sort(ps,ps+n);

      Point cur = Point(0,0);
      Point cur2 = Point(0,0);
      double L = 0;
      rep(_,n)
        {
          if(!_)
            {
              cur = ps[0];
              use[0] = true;
              L += sqrt(norm(cur-ps[0]));
              continue;
            }
          cout << "cur " << cur.x << "," << cur.y << endl;
          cout << "cur2 " << cur2.x << "," << cur2.y << endl;
          int next = -inf;
          double maxArg = -inf;

          rep(i,n)
            {
              if(use[i])continue;
              //cout << "i = "<< i << endl;

              Point cc = cur - cur2;
              double arg = atan2(ps[i].y-cc.y,ps[i].x-cc.x);

              if(!equals(arg,toRad(90)) && arg > toRad(90))arg =
toRad(-180)-(toRad(180)-arg); cout << i << " arg = " << arg*180/M_PI << " max :
" << maxArg << endl; if(!equals(arg,maxArg) && arg > maxArg)
                {
                  maxArg = arg;
                  next = i;
                }
              else if(equals(arg,maxArg) &&  norm(ps[next]-cur) >
norm(ps[i]-cur) )
                {
                  next = i;
                }
              //cout << endl;
            }
          cout << "next = " << next << " " << ps[next].x << "," << ps[next].y <<
endl; assert(next != -inf); L +=
sqrt(pow(cur.x-ps[next].x,2)+pow(cur.y-ps[next].y,2));


          cur2 = cur;
          cur = ps[next];
          use[next] = true;
          cout << endl << endl;
        }

      printf("%.1f\\n",L);
    }
  return 0;
}





*/

Error: 0
8
60 70
20 40
50 50
70 10
10 70
80 90
70 50
100 50
5
60 50
0 80
60 20
10 20
60 80


Fixed submission:


#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 28)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define all(n) (n).begin(), (n).end()

using namespace std;

double EPS = 1e-9;

bool equals(double a, double b) { return fabs((a) - (b)) < EPS; }

class Point {
public:
  int x, y;

  Point(int x = -1, int y = -1) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(int a) { return Point(a * x, a * y); }
  Point operator/(int a) { return Point(x / a, y / a); } // ※イケメンに限る

  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }
};

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(-1, -1), Point p2 = Point(-1, -1))
      : p1(p1), p2(p2) {}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }

double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double norm(Point a) { return a.x * a.x + a.y * a.y; }
/*
double getArg(Point A,Point B,Point C)
{
  double a = sqrt(norm(B-C));
  double b = sqrt(norm(A-C));
  double c = sqrt(norm(A-B));
  double cs = (b*b+c*c-a*a)/(2.0*b*c);
  return acos(cs);
}
*/
double getArgV2(Point A, Point B) {
  double a = sqrt(norm(A));
  double b = sqrt(norm(B));
  return acos(dot(A, B) / (a * b));
}

bool cmp(const Point &a, const Point &b) {
  if (a.x != b.x)
    return a.x < b.x;
  return a.y < b.y;
}

int main() {
  int n;
  while (cin >> n, n) {
    cerr << n << endl;
    Point ps[n];
    bool used[n];
    Point cur1 = Point(0, 0);
    Point cur2 = Point(0, 0);
    rep(i, n) {
      cin >> ps[i].x >> ps[i].y;
      cerr << ps[i].x << " " << ps[i].y << endl;
      used[i] = false;
    }
    sort(ps, ps + n, cmp);
    double L = 0;
    rep(_, n) {
      if (_ == 0) {
        L += sqrt(norm(ps[0] - cur1));
        cur1 = ps[0];
        used[0] = true;
        // cout << "L = " << L << endl;
        continue;
      }
      double minArg = inf;
      double minDist = inf;
      int minpos = -inf;
      rep(i, n) {
        if (used[i])
          continue;
        // cout << "cur1(" << cur1.x << "," << cur1.y << ")" << endl;
        // cout << "cur2(" << cur2.x << "," << cur2.y << ")" << endl;
        // cout << "ps["<<i<<"](" << ps[i].x << "," << ps[i].y << ")" << endl;

        double arg = getArgV2(cur1 - cur2, ps[i] - cur1);

        // cout << arg*180/M_PI << " ::: " << endl;
        if (!equals(arg, minArg) && arg < minArg) {
          minpos = i;
          minArg = arg;
          minDist = sqrt(norm(cur1 - ps[i]));
        }
        if (equals(arg, minArg) &&
            sqrt(norm(cur1 - ps[minpos])) > sqrt(norm(cur1 - ps[i]))) {
          minDist = sqrt(norm(cur1 - ps[i]));
          minpos = i;
        }
      }
      // cout << "cur1 (" << cur1.x << "," << cur1.y << ")" << endl;
      // cout << "phase #" << _ << " " << minpos << "(" << ps[minpos].x << ","
      // << ps[minpos].y << ")" << endl; cout << "that arg is " <<
      // minArg*180/M_PI << endl;

      // assert(minpos != -inf);
      used[minpos] = true;
      L += sqrt(norm(cur1 - ps[minpos]));
      cur2 = cur1;
      cur1 = ps[minpos];

      // cout << "L = " << L << endl << endl;
    }
    // L *= 10.0;
    // L = round(L);
    // L /= 10.0;
    // cout << setiosflags(ios::fixed) << setprecision(1) << L << endl;
    printf("%.1f\\n", L);
  }
  return 0;
}