• 18 徐州 M


    听了遍dls的讲解觉得这是个沙比题,结果调了两个小时。。。

    主要注意的点有两个,

    一个是 找每个灯覆盖的区间,这个用叉积看一下夹角即可

    一个是 覆盖的时候点覆盖比边覆盖好写(个人感觉)

    点覆盖的话,如果当前光源能照到[l,r]的点,那下一次直接找<=r的就可以了,最后判断覆盖n个点

    边的话,如果是[l,r]的边,那么下一次就要找<=r+1的,最后判断覆盖n-1条边。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <vector>
     6 using namespace std;
     7 typedef double db;
     8 const int N = 2005;
     9 const db eps = 1e-6;
    10 const db pi = acos(-1);
    11 int sign(db k){
    12     if (k>eps) return 1; else if (k<-eps) return -1; return 0;
    13 }
    14 int cmp(db k1,db k2){return sign(k1-k2);}
    15 struct point{
    16     db x,y;
    17     point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
    18     point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
    19     point operator * (db k1) const{return (point){x*k1,y*k1};}
    20     point operator / (db k1) const{return (point){x/k1,y/k1};}
    21     int operator == (const point &k1) const{return cmp(x,k1.x)==0&&cmp(y,k1.y)==0;}
    22 };
    23 db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
    24 db dot(point k1,point k2){return k1.x*k2.y-k1.y+k2.x;}
    25 int t,n,m;
    26 point p[N],s[N];
    27 struct O{
    28     int s,t,inx;
    29     bool operator <(const O &o)const{
    30         if(s==o.s)return t>o.t;
    31         else return s<o.s;
    32     }
    33 };
    34 vector<O>v;
    35 vector<int> ans,tmp;
    36 void slove(){
    37     for(int l=0;l<v.size();l++){
    38         tmp.clear();
    39         int cur=l;
    40         tmp.push_back(v[cur].inx);
    41         while (v[cur].t<v[l].s+n){
    42             int mx = v[cur].t;
    43             for(int r=l+1;r<v.size()&&v[r].s<=mx;r++){
    44                 if(v[r].t>v[cur].t) cur=r;
    45             }
    46             if(v[cur].t==mx)break;
    47             tmp.push_back(v[cur].inx);
    48         }
    49         if(v[cur].t>=v[l].s+n&&(ans.empty()||tmp.size()<ans.size()))
    50             ans=tmp;
    51     }
    52 }
    53 int main(){
    54     scanf("%d",&t);
    55     while(t--){
    56         v.clear();ans.clear();
    57         scanf("%d%d",&n,&m);
    58         for(int i=0;i<n;i++){//
    59             scanf("%lf%lf",&p[i].x,&p[i].y);
    60             p[i+n]=p[i];
    61         }
    62         for(int i=0;i<m;i++){
    63             scanf("%lf%lf",&s[i].x,&s[i].y);
    64         }
    65         for(int i=0;i<m;i++){
    66             int l=0,r;
    67             for(int j=0;j<n;j++){
    68                 if(cross(p[j+1]-p[j],p[j]-s[i])>0&&cross(p[j]-p[j-1+n],p[j-1+n]-s[i])<=0)
    69                     l=j;
    70             }
    71             r=l;
    72             while (r<=l+n){
    73                 if(cross(p[r+1]-p[r],p[r]-s[i])>0)r++;
    74                 else break;
    75             }
    76             v.push_back({l,r,i+1});//点覆盖
    77             //if(r+n<2*n)v.push_back({l+n,r+n,i+1});
    78         }
    79         sort(v.begin(),v.end());
    80         slove();
    81         if(ans.empty())
    82             printf("-1
    ");
    83         else {
    84             printf("%d
    ", ans.size());
    85             for (int i = 0; i < ans.size(); i++) {
    86                 printf("%d%c", ans[i], i == ans.size() - 1 ? '
    ' : ' ');
    87             }
    88         }
    89     }
    90 }
    91 /**
    92 1
    93 3 1
    94 0 0
    95 1 0
    96 0 1
    97 -1 -1
    98  */
    View Code
  • 相关阅读:
    数据库(2019年10月30日)
    (面试题)反射(2019年10月28日)
    反射(2019年10月28日)
    常微分复习重点
    重要定理及其证明
    实变函数复习重点
    泛函分析重点定理
    自旋玻璃简介
    Fnight博文发布规范
    [分析力学]解题思路
  • 原文地址:https://www.cnblogs.com/MXang/p/10625525.html
Copyright © 2020-2023  润新知