列表

详情


NC225893. Illuminations

描述

You are given a convex polygon with  vertices and  different points strictly outside the polygon which are all legal positions to install illuminants.

An illuminant can light up some exterior boundaries of the polygon. Your task is to install the least number of illuminants to light up all exterior boundaries of the polygon and provide a feasible scheme.


输入描述

The first line contains two integers  and .

Each of the following  lines describes a vertex on the convex polygon with two integers x and y , indicating the coordinates of a vertex on the polygon. All these vertices are given in counter-clockwise order and any three of them are not collinear.

Then the following  lines contain m different points outside the polygon describing all legal positions to install illuminants. The i-th line contains two integers   and , indicating the coordinates of the -th position. All these positions would not lie in some extension lines for the sides of the polygon.

输出描述

If it is impossible to light up all exterior boundaries of the polygon, output a single line with a single integer .

Otherwise output two lines. Firstly, output a line with a single integer , representing the least number of illuminants needed to light up all the boundaries. Then, output a line with  space-separated distinct integers, describing a feasible scheme, each of which is the index of a selected position.

All feasible schemes are allowed, so you can output any of them.

示例1

输入:

3 3
0 0
1 0
0 1
-1 -1
3 -1
-1 3

输出:

2
2 1

示例2

输入:

3 1
0 0
1 0
0 1
-1 -1

输出:

-1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 234ms, 内存消耗: 18476K, 提交时间: 2021-08-17 20:36:19

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=2e5+5;
struct node{
	int x,y;
    node operator -(const node b)const{
        return (node){x-b.x,y-b.y};
    }
    ll operator *(node b){
        return (ll)x*b.y-(ll)b.x*y;
    }
}p[M],q;
int id[M];
int n,f[20][M];
template <typename F>
int find(F f){
	bool up=f(0,1);
	int l=0,r=n;
	while(l!=r){
		int m=(l+r)/2;
		if(f(0,m)){
			if(up)l=m+1;
			else r=m;
		}else{
			if(f(m,m+1))r=m;
			else l=m+1;
		}
	}
	return l;
}
int main(){
	int m;
	scanf("%d%d",&n,&m); 
	for(int i=0;i<n;i++)scanf("%d%d",&p[i].x,&p[i].y);
	reverse(p,p+n);//顺时针方向 
	p[n]=p[0];
	for(int i=1;i<=m;i++){
		scanf("%d%d",&q.x,&q.y);
		int l=find([&](int i,int j){return (p[i]-q)*(p[j]-q)>0;});
		int r=find([&](int i,int j){return (p[i]-q)*(p[j]-q)<0;});
		l%=n,r%=n;
		int len=(r-l+n)%n;
		if(len>f[0][l]){
			f[0][l]=len;
			id[l]=i;
		}
	}
	for(int i=0;i<2*n;i++){
		int len=f[0][i%n]-1;
		if(len>f[0][(i+1)%n]){
			f[0][(i+1)%n]=len;
			id[(i+1)%n]=id[i%n];
		}
	}
	for(int i=0;i<n;i++){
		if(f[0][i])continue;
		puts("-1");
		return 0;
	}
	for(int j=1;j<20;j++){
		for(int i=0;i<n;i++){
			f[j][i]=min(f[j-1][i]+f[j-1][(i+f[j-1][i])%n],n);
		}
	}
	int ans=1e9,st=0;
	for(int i=0;i<n;i++){
		int x=i,sum=0,cnt=0;
		for(int j=19;j>=0;j--)
		if(sum+f[j][x]<n){
			sum+=f[j][x];
			x=(x+f[j][x])%n;
			cnt+=1<<j;
		}
		if(cnt+1<ans){
			ans=cnt+1;
			st=i;	
		}
	}
	printf("%d\n",ans);
	while(ans--){
		printf("%d%c",id[st]," \n"[ans==0]);
		st=(st+f[0][st])%n;
	}
	return 0;
}

上一题