静かで孤独な日記

のんびりたまに

ABC033 D 三角形の分類

using namespace std;
//const ll MOD=(ll)1e9+7;
//const ll inf=(ll)1e14;
const double PI=acos(-1.0);
const double EPS=1e-10;
const int dy[]={1,0,-1};
const int dx[]={1,0,-1};
int n,m,h,w;
string s;
ll x[2001],y[2001];

int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.precision(10);
  cout<<fixed;
#ifdef LOCAL_DEFINE
  FILE *stream1;
  //FILE *stream2;
  stream1=freopen("in","r",stdin);
  //stream2=freopen("out","w",stdout);
  if(stream1==NULL)return 0;
  //if(stream2==NULL)return 0;
#endif
  cin>>n;
  for(int i=0;i<n;i++){
    cin>>x[i]>>y[i];
  }
  ll ans1=0,ans2=0,ans3=0;
  for(int i=0;i<n;i++){
    vector<double> v;
    for(int j=0;j<n;j++){
      if(i==j)continue;
      v.push_back(atan2(y[j]-y[i],x[j]-x[i]));
    }
    sort(v.begin(),v.end());
    for(int j=0;j<n-1;j++){
      v.push_back(v[j]+2*PI);
    }
    for(int j=0;j<n-1;j++){
      int a=lower_bound(v.begin(),v.end(),v[j]+PI/2-EPS)-v.begin();
      int b=upper_bound(v.begin(),v.end(),v[j]+PI/2+EPS)-v.begin();
      int c=lower_bound(v.begin(),v.end(),v[j]+PI)-v.begin();
      ans2+=b-a;
      ans3+=c-b;
    }
  }
  ans1=(ll)n*(n-1)*(n-2)/6-ans2-ans3;
  print(ans1,ans2,ans3);
#ifdef LOCAL_DEFINE
  cerr<<"Time elapsed: "<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
  fclose(stream1);
  //fclose(stream2);
#endif
  return 0;
}

  • 2種類求めて全体から2種類分引いて残りを求めるのはわかるけど、慣れてないのもあって手が出なかった。
  • 角度で持ってあげるのいいね。
  • あとEPSの使い方がわからなかったので少し戸惑った(写真)