Kadj Squares 几何思维

Kadj Squares

题意:不断加45°角站立的正方形,在互不相交的情况下,使得每个正方形底端点尽量靠左,求在上方视角可以看到的正方形编号

解法:

先求每个正方形左右端点

L[i] R[i] X[i] 分别表示 i正方形的左端点、右端点、边长

因为每个新正方形 i 总会和另外一个正方形 j 的一条边重合,由此可计算新正方形左端点坐标L= R[j]-fabs(X[i]-X[j])/sqrt(2)

每加一个正方形,和之前所有正方形枚举计算出L  取所有L中的最大值,是合法情况 且 是最优解

其次求

每个正方形左右有效端点(上方可见范围)

更新每个正方形之间的覆盖影响

i 正方形 对前面 j 正方形的影响:

1.若X[j]<X[i] 则 j 正方形 在 i 正方形下方 , 更新 j 正方形有效端点 

2.若X[j]>X[i] 则 j 正方形 在 i 正方形上方,更新 i 正方形有效端点

更新完后,若 i 正方形 可见范围 >0 ,则可见,输出

#include  <map>
#include  <set>
#include  <cmath>
#include  <math.h>
#include  <queue>
#include  <cstdio>
#include  <vector>
#include  <climits>
#include  <cstring>
#include  <cstdlib>
#include  <iostream>
#include  <algorithm> 
#define down DOWN
using namespace std;
double X[55];
double L[55],R[55];
double g=sqrt(double(2));
int main() 
{
	int n;
	while(~scanf("%d",&n)&&n)	
	{
		memset(vis,0,sizeof(vis)) ;
		double mx=0;
		int mxi=-1;
		for(int i=0;i<n;i++)
		{
			scanf("%lf",&X[i]);
		}
		for(int i=0;i<n;i++)
		{
			double l=0;
			for(int j=0;j<i;j++)
			{
				l=max(l,R[j]-fabs(X[i]-X[j])/g);
			}
			L[i]=l;
			R[i]=l+X[i]*g;
		}

		int flag=0;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<i;j++)
			{
				if(X[j]<X[i]&&L[i]<R[j])
				{
					R[j]=L[i];
				}
				if(X[i]<X[j]&&R[j]>L[i])
				{
					L[i]=R[j];
				}
			}
		}
		for(int i=0;i<n;i++)
		{
			if(R[i]-L[i]>1e-10)
			{
				if(flag==0)
				{					
				flag=1;
				printf("%d",i+1);
				}
				else printf(" %d",i+1);
			}
		}
		
		printf("\n");
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值