题意:
题意:依次给出n个正方形的边长,要求在第一象限内依次放入正方形,满足:
①放入第i个正方形时,第i个正方形与前面的正方形都不重合
②放入正方形时,要求一个顶点在x轴上,且坐标值最小
其实看这个图就懂规则了
求放完所有正方形后,从高处向下照射竖直平行光,有部分会被照亮的正方形序号。
推荐博客:https://www.cnblogs.com/terra/p/7067517.html https://blog.csdn.net/wl16wzl/article/details/82106811
解法1:
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
typedef long long ll;
using namespace std;
const int N=100010;
int s[110],t[110];
int main()
{
int n;
while(scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++)
scanf("%d",&s[i]);
for(int i=1;i<=n;i++)
{
t[i]=s[i];
for(int j=1;j<i;j++)
{
t[i]=max(t[i],t[j]+2*min(s[j],s[i]));
}
}
for(int i=1;i<=n;i++)
{
int l=0,r=0;
for(int j=1;j<i;j++)
{
if(s[j]>s[i])
l=max(l,s[j]+s[i]-(t[i]-t[j]));
}
for(int j=i+1;j<=n;j++)
{
if(s[j]>s[i])
r=max(r,s[j]+s[i]-(t[j]-t[i]));
}
if(l+r<2*s[i])
printf("%d ",i);
}
printf("\n");
}
return 0;
}
解法2:
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
typedef long long ll;
using namespace std;
const int N=100010;
double s[110],t[110];
int main()
{
int n;
while(scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++)
scanf("%lf",&s[i]);
//s[i]为正方形边长的sqrt(2)倍
s[0]=0;t[0]=0;
double inf=0;
for(int i=1;i<=n;i++)
{
t[i]=s[i]/2;
for(int j=1;j<i;j++)
t[i]=max(t[i],t[j]+min(s[j],s[i]));
inf=max(inf ,t[i]+s[i]/2);
}
for(int i=1;i<=n;i++)
{
double l=inf,r=0;
for(int j=1;j<i;j++)
{
if(s[j]>s[i])
r=max(r,t[j]+s[j]/2);
}
for(int j=i+1;j<=n;j++)
{
if(s[j]>s[i])
l=min(l,max(t[j]-s[j]/2,double(0)));
}
if(l<=t[i]-s[i]/2||r>=t[i]+s[i]/2||r>=l)
continue;
else
printf("%d ",i);
}
printf("\n");
}
return 0;
}