极限

题解链接
https://www.cnblogs.com/weeping/p/7655975.html
https://blog.csdn.net/fp_hzq/article/details/7972428
注意atan等反三角函数的应用和圆上的几何关系。
代码如下
/*
题解链接
https://www.cnblogs.com/weeping/p/7655975.html
https://blog.csdn.net/fp_hzq/article/details/7972428
注意atan等反三角函数的应用和圆上的几何关系。
*/
#define method_2
#ifdef method_1
/*
2700msAC
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=300+5;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
struct node {
double x,y;
bool operator<(const node& h)const {
return x<h.x||(abs(x-h.x)<eps&&y<h.y);
}
} p[maxn];
int n,ans;
void init() {
ans=1;
}
double dis(node i,node j) { //计算i和j距离的平方
return (i.x-j.x)*(i.x-j.x)+(i.y-j.y)*(i.y-j.y);
}
int solve(node a,node b) {
node tmp;
tmp.x=(a.x+b.x)/2,tmp.y=(a.y+b.y)/2;
double angle=acos(-1.0)/2+atan2(a.y-b.y,a.x-b.x);
double len=sqrt(1-dis(a,b)/4);
tmp.x+=cos(angle)*len;
tmp.y+=sin(angle)*len;
int res=0;
for(int i=1; i<=n; i++) {
if(dis(p[i],tmp)<=1+eps) res++;
}
// D(angle);D(res);E;
return res;
}
int main() {
ios::sync_with_stdio(false);
//freopen("Circle and Points.in","r",stdin);
while(cin>>n) {
if(!n) break;
for(int i=1; i<=n; i++) cin>>p[i].x>>p[i].y;
if(n==1) {
cout<<1<<endl;
continue;
}
init();
sort(p+1,p+n+1);
for(int i=1; i<=n; i++) for(int j=i+1; j<=n&&(p[j].x-p[i].x)<=2; j++) if(dis(p[i],p[j])<=4) {
ans=max(ans,max(solve(p[i],p[j]),solve(p[j],p[i])));
}
cout<<ans<<endl;
}
return 0;
}
#endif
#ifdef method_2
/*
800msAC
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=300+5;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
struct node {
double x,y;
} p[maxn];
struct arc {
int flag;
double rad;
bool operator<(const arc& h)const {
return rad<h.rad;
}
} q[maxn<<1];
int n,ans;
void init() {
ans=1;
}
double dis(node i,node j) { //计算i和j距离的平方
return (i.x-j.x)*(i.x-j.x)+(i.y-j.y)*(i.y-j.y);
}
void solve() {
for(int i=1; i<=n; i++) {
int cnt=0,res=0;
double dist;
for(int j=1; j<=n; j++) {
if((dist=dis(p[i],p[j]))<=4&&i!=j) { //这边不能写成 (dist=dis(p[i],p[j])<=4)&&i!=j
double rad=acos(sqrt(dist)/2);
double tmp=atan2(p[j].y-p[i].y,p[j].x-p[i].x);
q[++cnt].flag=1;
q[cnt].rad=tmp-rad;
q[++cnt].flag=0;
q[cnt].rad=tmp+rad;
}
}
sort(q+1,q+cnt+1);
for(int j=1; j<=cnt; j++) {
if(q[j].flag) res++;
else res--;
ans=max(ans,res+1);//包括i点
// D(q[j].flag);D(q[j].rad);E;
}
// D(res);E;
}
}
int main() {
ios::sync_with_stdio(false);
//freopen("Circle and Points.in","r",stdin);
while(cin>>n) {
if(!n) break;
for(int i=1; i<=n; i++) cin>>p[i].x>>p[i].y;
if(n==1) {
cout<<1<<endl;
continue;
}
init();
solve();
cout<<ans<<endl;
}
return 0;
}
#endif
POJ 1418: Viva Confetti
题解链接 http://www.hankcs.com/program/algorithm/poj-1418-viva-confetti.html
两层抽象:
1 将区域抽象为圆弧构成的区域。
2 通过判断圆弧的中点,来判断是否遮盖(圆弧用极角表示,另需加入弧度为0和2Π的圆弧,使得所有圆弧都会被考虑到)
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
题解链接 http://www.hankcs.com/program/algorithm/poj-1418-viva-confetti.html
两层抽象:
1 将区域抽象为圆弧构成的区域。
2 通过判断圆弧的中点,来判断是否遮盖(圆弧用极角表示,另需加入弧度为0和2Π的圆弧,使得所有圆弧都会被考虑到)
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=100+5;
const int INF=0x3f3f3f3f;
const double eps=4e-13;
const double pi=acos(-1.0);
struct node{
double x,y,r;
}a[maxn];
int n,cnt,vis[maxn],ans;
double rad[maxn*maxn];
void init(){
ans=0;
memset(vis,0,sizeof(vis));
}
double normalizeangle(double angle){
if(angle<0) angle+=2*pi;
if(angle>=2*pi) angle-=2*pi;
return angle;
}
int hit(double x,double y){
for(int i=n;i>=1;i--){
if(a[i].r*a[i].r>(x-a[i].x)*(x-a[i].x)+(y-a[i].y)*(y-a[i].y)) return i;
}
return -1;
}
double dis(int i,int j){
return (a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);
}
int main() {
ios::sync_with_stdio(false);
//freopen("Viva Confetti.in","r",stdin);
while(cin>>n){
if(!n) break;
init();
for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y>>a[i].r;
for(int i=1;i<=n;i++){
cnt=0;
rad[++cnt]=0.0,rad[++cnt]=2.0*pi;
for(int j=1;j<=n;j++){
if(i==j) continue;
if((a[i].r+a[j].r<sqrt(dis(i,j)))||(a[i].r+sqrt(dis(i,j))<a[j].r)||(sqrt(dis(i,j))+a[j].r<a[i].r)) continue;
double d=atan2(a[j].y-a[i].y,a[j].x-a[i].x);
double e=acos((a[i].r*a[i].r+dis(i,j)-a[j].r*a[j].r)/(2*a[i].r*sqrt(dis(i,j))));
rad[++cnt]=normalizeangle(d+e),rad[++cnt]=normalizeangle(d-e);
}
sort(rad+1,rad+cnt+1);
for(int j=1;j<=cnt-1;j++){
double angle=(rad[j]+rad[j+1])/2.0;
for(int k=-1;k<=1;k+=2){
int res=hit(a[i].x+cos(angle)*(a[i].r+eps*k),a[i].y+sin(angle)*(a[i].r+eps*k));
if(res!=-1) vis[res]=1;
}
}
}
for(int i=1;i<=n;i++) if(vis[i]) ans++;
cout<<ans<<endl;
}
return 0;
}
#endif
#ifdef method_2
/*
*/
#endif
#ifdef method_3
/*
*/
#endif
平面扫描
POJ 3168: Barn Expansion
题解链接 https://blog.csdn.net/aozil_yang/article/details/52060501
其中method_1未通过,反例见代码注释。
代码如下
/*
题解链接 https://blog.csdn.net/aozil_yang/article/details/52060501
*/
#define method_3
#ifdef method_1
/*
这个方法有错,反例如下。
3
1 0 2 5
0 1 1 2
0 3 1 4
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=25000+5;
const int INF=0x3f3f3f3f;
int n,cntx=0,cnty=0,flag[maxn]={0},ans=0;
struct nodex{
int x,y1,y2,id;
bool operator<(const nodex& h)const{return x!=h.x?x<h.x:y1<h.y1;}
}linex[maxn<<1];
struct nodey{
int y,x1,x2,id;
bool operator<(const nodey& h)const{return y!=h.y?y<h.y:x1<h.x1;}
}liney[maxn<<1];
inline bool overlap(int i,int j,int f){
if(f==0){
return linex[j].y1<=linex[i].y2;
}
if(f==1){
return liney[j].x1<=liney[i].x2;
}
}
int main() {
// ios::sync_with_stdio(false);
//freopen("Barn Expansion.in","r",stdin);
scanf("%d",&n);
int x1,y1,x2,y2;
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
linex[++cntx].x=x1,linex[cntx].y1=y1,linex[cntx].y2=y2,linex[cntx].id=i;
linex[++cntx].x=x2,linex[cntx].y1=y1,linex[cntx].y2=y2,linex[cntx].id=i;
liney[++cnty].y=y1,liney[cnty].x1=x1,liney[cnty].x2=x2,liney[cnty].id=i;
liney[++cnty].y=y2,liney[cnty].x1=x1,liney[cnty].x2=x2,liney[cnty].id=i;
}
sort(linex+1,linex+cntx+1);
sort(liney+1,liney+cnty+1);
for(int i=1;i<=cntx-1;i++){
// D(linex[i].x);D(linex[i].y1);D(linex[i].y2);E;
if(linex[i].x!=linex[i+1].x) continue;
if(overlap(i,i+1,0)) flag[linex[i].id]=flag[linex[i+1].id]=1;
}
for(int i=1;i<=cnty-1;i++){
if(liney[i].y!=liney[i+1].y) continue;
if(overlap(i,i+1,1)) flag[liney[i].id]=flag[liney[i+1].id]=1;
}
for(int i=1;i<=n;i++) if(flag[i]==0){
// D(i);E;
ans++;
}
printf("%d",ans);
return 0;
}
#endif
#ifdef method_2
/*
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=25000+5;
const int INF=0x3f3f3f3f;
int n,cntx=0,cnty=0,flag[maxn]={0},ans=0;
struct nodex{
int x,y1,y2,id;
// bool operator<(const nodex& h)const{return x!=h.x?x<h.x:y1<h.y1;}
}linex[maxn<<1];
struct nodey{
int y,x1,x2,id;
// bool operator<(const nodey& h)const{return y!=h.y?y<h.y:x1<h.x1;}
}liney[maxn<<1];
bool cmpx(nodex i,nodex j){
return (i.x<j.x)||(i.x==j.x&&i.y1<j.y1);
}
bool cmpy(nodey i,nodey j){
return (i.y<j.y)||(i.y==j.y&&i.x1<j.x1);
}
int main() {
// ios::sync_with_stdio(false);
//freopen("Barn Expansion.in","r",stdin);
scanf("%d",&n);
int x1,y1,x2,y2;
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
linex[++cntx].x=x1,linex[cntx].y1=y1,linex[cntx].y2=y2,linex[cntx].id=i;
linex[++cntx].x=x2,linex[cntx].y1=y1,linex[cntx].y2=y2,linex[cntx].id=i;
liney[++cnty].y=y1,liney[cnty].x1=x1,liney[cnty].x2=x2,liney[cnty].id=i;
liney[++cnty].y=y2,liney[cnty].x1=x1,liney[cnty].x2=x2,liney[cnty].id=i;
}
sort(linex+1,linex+cntx+1,cmpx);
sort(liney+1,liney+cnty+1,cmpy);
for(int i=1;i<=cntx;i++){
// D(linex[i].x);D(linex[i].y1);D(linex[i].y2);E;
int nxt_i=cntx;
for(int j=i+1;j<=cntx;j++) if(linex[i].x!=linex[j].x){
nxt_i=j-1;break;
}
int up=linex[i].y2;
for(int j=i+1;j<=nxt_i;j++){
if(linex[j].y1<=up){
flag[linex[j].id]=flag[linex[j-1].id]=1;
}
if(linex[j].y2>=up){
up=linex[j].y2;
}
}
i=nxt_i; //这句话保证对于每条线只处理一次,即保证处理过程复杂度为O(n)
}
for(int i=1;i<=cnty;i++){
int nxt_i=cnty;
for(int j=i+1;j<=cnty;j++) if(liney[i].y!=liney[j].y){
nxt_i=j-1;break;
}
int up=liney[i].x2;
for(int j=i+1;j<=nxt_i;j++){
if(liney[j].x1<=up){
flag[liney[j].id]=flag[liney[j-1].id]=1;
}
if(liney[j].x2>=up){
up=liney[j].x2;
}
}
i=nxt_i; //这句话保证对于每条线只处理一次,即保证处理过程复杂度为O(n)
}
for(int i=1;i<=n;i++) if(flag[i]==0){
// D(i);E;
ans++;
}
printf("%d",ans);
return 0;
}
#endif
POJ 3293: Rectilinear polygon
题解链接 http://www.mamicode.com/info-detail-1716765.html
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
题解链接 http://www.mamicode.com/info-detail-1716765.html
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=100000+5;
const int INF=0x3f3f3f3f;
int T,n,con[maxn][2],lcnt,ans;
struct node{
int x,y,id;
}p[maxn];
struct nodex{
int x,y1,y2;
}linex[maxn];
bool cmpx(node i,node j){
return i.x!=j.x?i.x<j.x:i.y<j.y;
}
bool cmpy(node i,node j){
return i.y!=j.y?i.y<j.y:i.x<j.x;
}
void init(){
ans=0,lcnt=0;
}
bool check(node i,node j){ //判断点i和点j组成的横线是否与之前的任意一条竖线相交
int x1=i.x,x2=j.x,y=i.y;
for(int i=1;i<=lcnt;i++){
if(x1<linex[i].x&&x2>linex[i].x&&y<linex[i].y2&&y>linex[i].y1) return true;
}
return false;
}
int main() {
// ios::sync_with_stdio(false);
//freopen("Rectilinear polygon.in","r",stdin);
scanf("%d",&T);
while(T--){
init();
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y),p[i].id=i;
sort(p+1,p+n+1,cmpx);
int flag=0,cnt=1;
for(int i=2;i<=n&&!flag;i++){
if(p[i].x!=p[i-1].x){
if(cnt&1) flag=1;
cnt=1;
}
else{
cnt++;
if((cnt&1)==0){
ans+=p[i].y-p[i-1].y;
con[p[i].id][0]=p[i-1].id;
con[p[i-1].id][0]=p[i].id;
linex[++lcnt].x=p[i].x,linex[lcnt].y1=p[i-1].y,linex[lcnt].y2=p[i].y;
}
}
}
sort(p+1,p+n+1,cmpy);
cnt=1;
for(int i=2;i<=n&&!flag;i++){
if(p[i].y!=p[i-1].y){
if(cnt&1) flag=1;
cnt=1;
}
else{
cnt++;
if((cnt&1)==0){
ans+=p[i].x-p[i-1].x;
con[p[i].id][1]=p[i-1].id;
con[p[i-1].id][1]=p[i].id;
if(check(p[i-1],p[i])) flag=1;
}
}
}
//依次连接各个直角顶点
int pcnt=0,t=0,x=1;
while(1){
x=con[x][t];
t^=1;
pcnt++;
if(x==1||flag) break; //x==1表示连回自身
}
if(pcnt!=n) flag=1; //图不连通
if(flag) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
#endif
POJ 2482: Stars in Your Window
题解链接 https://www.jianshu.com/p/f598203aa288
网友评论