zoukankan      html  css  js  c++  java
  • 【留坑】模拟+极角排序+预处理——ICPC PNWRC 2019 H

     做的我要吐了。。留着吧以后再看看

    /*
    两两枚举起始的点,然后按题意模拟寻找下去,为了加速,预处理nxt[i][j]表示直线p[i]->p[j]旋转时,下一个碰到点的下标
     
    */
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <math.h>
    using namespace std ;
    const double PI = 3.14159265358979 ;
    double fixang(double a) {
       if (a < 0)a += PI ;
       if (a > PI)a -= PI ;
       return a ;
    }
    int main(int argc, char *argv[]) {
       int n ;
       cin >> n ;
       vector<double> x(n), y(n) ;
       for (int i=0; i<n; i++)
          cin >> x[i] >> y[i] ;
       vector<pair<double, int>> sortme ;
       vector<vector<int>> next ;
       vector<vector<double>> angs ;
       
       for (int i=0; i<n; i++) {
          sortme.clear() ;
          for (int j=0; j<n; j++)
             if (i != j) {
                double dy = y[j] - y[i] ;
                double dx = x[j] - x[i] ;
                if (dy < 0 || (dy == 0 && dx < 0)) {
                   dy = - dy ;
                   dx = - dx ;
                }
                sortme.push_back({atan2(dy, dx),j}) ;
             }
          sort(sortme.begin(), sortme.end()) ;
          vector<int> v(n) ;
          vector<double> ang(n) ;
          //处理首位衔接 
          v[sortme[sortme.size()-1].second] = sortme[0].second ;
          ang[sortme[sortme.size()-1].second] =
                         fixang(sortme[0].first - sortme[sortme.size()-1].first) ;
          
          //以i为中点时的下一个点 
          for (int j=0; j+1<(int)sortme.size(); j++) {
             v[sortme[j].second] = sortme[j+1].second ;
             ang[sortme[j].second] = fixang(sortme[j+1].first - sortme[j].first) ;
          }
          
          next.push_back(v) ;
          angs.push_back(ang) ;
       }
       
       vector<vector<char> > seen ;
       for (int i=0; i<n; i++)
          seen.push_back(vector<char>(n)) ;
       
       int r = 0 ;
       for (int i=0; i<n; i++)
          for (int j=0; j<n; j++)
             if (i != j && !seen[i][j]) {//两两枚举起始直线(未被访问过的) 
                vector<int> cnts(n) ;
                int ii = i ;
                int jj = j ;
                double totspin = 0 ;
                while (1) {
                   cnts[ii]++ ;
                   seen[ii][jj] = 1 ;
                   int kk = next[ii][jj] ;//不停找下一个点,构成新的直线 
                   totspin += angs[ii][jj] ;//累加转过的角度 
                   jj = ii ;
                   ii = kk ;
                   if (ii == i && jj == j && totspin >= 1.5 * PI)//重新回到原来的点 
                      break ;
                }
                for (auto v : cnts)
                   r = max(r, v) ;
             }
       cout << r << endl ;
    }
  • 相关阅读:
    Qt编写安防视频监控系统1-通道切换
    Qt编写数据可视化大屏界面电子看板12-数据库采集
    Serv-U
    CLAAS KGaA mbH
    法国雷诺
    Bulma
    react技术栈
    小程序开发
    上海hande
    30个极大提高开发效率的VSCode插件
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12844622.html
Copyright © 2011-2022 走看看