2018-2019 ACM-ICPC, Asia Xuzhou Regional Contest M - Rikka with Illuminations(计算几何)

https://codeforc.es/gym/102012/problem/M

我太难了!写了个垃圾代码wa了三天一直过不去最后代码又长又丑果断放弃。。。

题意

n个点,m个灯,问最少用多少个灯可以照亮全部点。

题解

显然贪心。

处理出每个灯的覆盖范围,贪心搞出保证覆盖当前点j的同时能往后覆盖的最大距离add[j],

最后枚举以每个点为起点的所需灯数,取最少情况输出即可。

 1 #define bug(x) cout<<#x<<" is "<<x<<endl
 2 #define IO std::ios::sync_with_stdio(0)
 3 #define ull unsigned long long
 4 #include <bits/stdc++.h>
 5 #define iter ::iterator
 6 #define pa pair<int,ll>
 7 #define pp pair<int,pa>
 8 using namespace  std;
 9 #define ll long long
10 #define mk make_pair
11 #define pb push_back
12 #define se second
13 #define fi first
14 #define ls o<<1
15 #define rs o<<1|1
16 const int N=1e5+5;
17 ll mod=998244353;
18 struct Point{
19     int x,y;
20 };
21 Point operator -(Point A,Point B){
22     return (Point){A.x-B.x,A.y-B.y};
23 }
24 ll Cross(Point A,Point B){
25     return (1ll*A.x*B.y-1ll*A.y*B.x);
26 }
27 Point p[N],t[N];
28 int add[N],id[N];
29 int T,n,m;
30 int main(){
31     scanf("%d",&T);
32     while(T--){
33         scanf("%d%d",&n,&m);
34         for(int i=0;i<n+m;i++){
35             add[i]=id[i]=0;            
36         }
37         for(int i=0;i<n;i++){
38             scanf("%d%d",&p[i].x,&p[i].y);
39         }
40         for(int i=0;i<m;i++){
41             scanf("%d%d",&t[i].x,&t[i].y);
42         }
43         for(int i=0;i<m;i++){
44             int l=0,r=0;
45             for(int j=1;j<n;j++){
46                 if(Cross(p[j]-t[i],p[l]-t[i])<0)l=j;
47                 if(Cross(p[j]-t[i],p[r]-t[i])>0)r=j;
48             }
49             for(int j=l;j!=r;j=(j+1)%n){
50                 j%=n;
51                 if(add[j]<(r-j+n)%n)add[j]=(r-j+n)%n,id[j]=i;
52             }
53         }
54         int f=0;
55         for(int i=0;i<n;i++){
56             if(!add[i]){
57                 f=1;
58                 break;
59             }
60         }
61         if(f){
62             printf("-1\n");
63             continue;
64         }
65         int ans=1e9,start=0;
66         for(int i=0;i<n;i++){
67             int cnt=0;
68             int j=i;
69             while(j<i+n){
70                 j+=add[j%n];
71                 cnt++;
72             }
73             if(cnt<ans){
74                 ans=cnt;
75                 start=i;
76             }
77         }
78         printf("%d\n",ans);
79         int i=start;
80         while(ans--){
81             printf("%d%c",id[i]+1,ans==0?'\n':' ');
82             i+=add[i]%n;
83         }
84     }
85 }

 

posted @ 2019-09-28 20:49  Venux  阅读(447)  评论(0编辑  收藏  举报